[英]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
的屬性,它只是一個空對象。 這個對象得到一些特殊處理。
當您執行一個new
的Function
,創建的對象將繼承其構造函數原型的所有屬性 。
像吼叫一樣
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.