簡體   English   中英

Javascript`new`運算符和原型

[英]Javascript `new` operator & prototype

假設我們創建一個名為'Shape'的函數,並在其原型上添加屬性'name'和方法'toString':

var Shape = function () {};
Shape.prototype.name = 'Shape';
Shape.prototype.toString = function () {
    return this.name;
}

console.log(Shape.name); // ''
console.log(Shape.toString()); // function () {}

var Triangle = new Shape();
console.log(Triangle.name); // 'Shape'
console.log(Triangle.toString()); // 'Shape'

'NEW'運算符做了兩件事:1。它指向'Triangle'2.它將'Triangle'[[proto]]指向Shape.prototype

然后我可以理解當我在Triangle上調用name和toString時,它會搜索它的原型鏈直到Shape.prototype。

但我的問題是為什么Shape不尋找它的屬性(即使它是一個對象)的方法和屬性?

謝謝。

當您訪問對象上的屬性時,Javascript會直接在對象上查找已直接添加到對象的任何屬性(這些屬性稱為“自己的”屬性)。 如果它沒有在那里找到屬性,那么它會查找原型鏈。

所以,當你這樣做時:

var Triangle = new Shape();
console.log(Triangle.toString()); // 'Shape'

它在名為Triangle的實際對象上查找.toString()屬性,但該對象上沒有該名稱的屬性。 因此,由於它沒有直接在對象上找到任何內容,因此它會查看原型並在那里找到Shape.prototype.toString()實現,這就是執行的內容。

原型的引用在創建時存儲在Triangle對象上。 它不存儲在.prototype屬性中 - 該屬性僅用於構造函數。 相反,每個JS版本都有自己的方式來存儲對原型的引用,並且它對於所有瀏覽器傳統上並不相同,並且它的存儲方式是非標准的。 它最初僅供JS引擎內部使用。 例如,Chrome將其存儲在名為obj.__proto__的屬性上,但IE卻沒有。 為了解決這種標准化的缺乏,有一種名為obj.getPrototypeOf()新方法,現在可以在現代瀏覽器中使用它來訪問給定對象的原型。 在任何情況下,JS引擎在解析在實際對象本身上找不到的屬性名時會自動搜索此原型。

如果你這樣做:

var Triangle = new Shape();
Triangle.toString = function() {
    return 'Shape named Triangle';
}
console.log(Triangle.toString()); // 'Shape named Triangle'

然后,javascript將首先找到您直接附加到對象的toString()實現,它將執行該實現而不是原型上的實現。

所以我根據我所知道的添加。

這里Shape是一個函數&一個函數只是一種特殊的對象,就像函數可以擁有的任何對象一樣。

函數自動獲得一個名為prototype的屬性,它只是一個空對象。 這個對象得到一些特殊處理。

當您執行一個newFunction ,創建的對象將繼承其構造函數原型的所有屬性

像吼叫一樣

var Shape = function () {};
Shape.prototype.name = 'Shape';
Shape.prototype.toString = function () {
    return this.name;  
}

當你說的時候

var Triangle = new Shape();

它是做什么的

var Triangle = {};
Triangle.name = Shape.prototype.name
Triangle.toString = Shape.prototype.toString;

“它將對象Triangle為委托給Shape.prototype。”

所以當你做的時候

Triangle.name //Shape
Triangle.toString() // Shape

但對於Shape你將不得不說

Shape.prototype.name //Shape
Shape.prototype.toString() //Shape

因為Triangle是一個object ,其中Shape是一個函數(一種對象),因此當你請求一個函數的屬性而它找不到它時,就不會搜索它的prototype屬性。 但是你可以修改Function.prototype.name/toSTring()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM