[英]constructor and prototype
有人可以解釋一下嗎?
function Foo() {
this.x = 1;
this.y = 2;
}
function FooProto() {
this.arrow = 1;
this.bow = 1;
}
document.writeln(Foo.prototype); // [object Object]
document.writeln(Foo.prototype.constructor); // function Foo() { x =1; y=2; }
我的理解是:Foo.prototype是一個Object,其構造函數屬性是Function Foo。 Foo。[[Prototype]]是Function.Prototype
obj = new Foo;
document.writeln(obj.constructor); // function Foo() { x =1; y=2; }
document.writeln(obj.constructor.prototype); // [object Object]
Foo.prototype = FooProto;
document.writeln(Foo.prototype); // function FooProto() { arrow = 1; bow = 2; }
document.writeln(Foo.prototype.constructor); // function Function() { [native code] }
問題1:如何使用[[Prototype]]進行查找。 如果有人能向我解釋,我將不勝感激。
document.writeln(obj.constructor); // function Foo() { x =1; y=2; } .. no change
document.writeln(obj.constructor.prototype); // function FooProto() { arrow = 1; bow = 2; }
anotherObj = new Foo;
document.writeln(anotherObj.constructor); // function Function() { [native code] }
document.writeln(anotherObj.constructor.prototype); // function Empty() {}
問題2:與問題1相同的問題.Javascript解釋器是如何執行查找的?
在解釋基於原型的代碼時,使用Object.create
來解釋內容要簡單得多。 Object.create
是一個函數,它接收一個原型對象並創建一個新的實例對象,該對象將原型對象作為其[[prototype]]
在對象中查找屬性時,工作方式如下:
每個對象都有自己的,不可變的[[prototype]]屬性。 這個屬性是秘密和隱藏的,除非你在Firefox中,你可以通過__proto__
獲取它。
在讀取屬性時,我們首先在對象本身中搜索它,如果我們在那里找不到它,我們遞歸搜索對象的[[prototype]]。
在編寫屬性時,我們總是編寫一個自己的屬性(我們永遠不會改變[[prototype]],即使它也具有我們正在設置的屬性)。
proto = {a:1};
child1 = Object.create(proto);
child2 = Object.create(proto);
child1.a = 2;
console.log(proto.a); //1
console.log(child1.a); //2
console.log(child2.a); //1
創建功能時
每當我們在Javascript中創建一個函數對象時,它都會附帶一個已經填充的prototype
屬性。這個prototype
是一個對象(繼承自Object.prototype)並且將constructor
屬性設置為相應的函數。
使用函數構造函數實例化對象時(new Foo)
使用函數prototype
作為其[[prototype]]創建一個新對象,並在該對象上運行該函數以初始化它。
我真的不想解釋第一種情況發生了什么,因為Foo.prototype = FooProto;
部分沒有意義,可能不是你想做的(記住原型應該是對象,而不是函數)
至於第二種情況,更改構造函數的prototype
屬性只會影響將來的實例(anotherObj)。 已創建對象的[[prototype]]屬性是秘密且不可變的,因此您無法更改它們。
Javascript中有兩個原型概念。 (我把它當作語言設計中的名字碰撞。)
原型鏈中的原型 。 它是最后一個答案中提到的內部屬性。 訪問它的首選方法是Object.getPrototypeOf
。
var a = {}; Object.getPrototypeOf(a); // Object {} Object.getPrototypeOf(Object.getPrototypeOf(a)); // null, the top of prototype chain. Object.getOwnPropertyNames(Object.getPrototypeOf(a)); // the methods inherited
每個構造函數 (我認為所有聲明的函數)都有自己的屬性“prototype”。 它在new
運營商中使用。
new
操作員執行兩個步驟。
- 首先是創建一個對象,其原型(第一個,說,[[Prototype]])被指定為構造函數的原型(第二個)。
- 二是運行的構造函數(從仰視
prototype.constructor
)與服用創建對象作為隱含參數this
。
現在你的情況:
第一個obj
是使用其[[Prototype]]屬性(某些引擎中的proto )創建的,分配為Foo.prototype。
obj.constructor === obj.__proto__.constructor === Foo.prototype.constructor === Foo
obj.constructor.prototype === Function.prototype
請注意,構造函數也是Function對象。
然后你改變了Foo
的原型。 這改變了obj.constructor.prototype
而不是obj.constructor
,它有不同的引用。 anotherObj
從以下new
運算符中獲得了一個新的[[Prototype]]。
這個問題已經存在多年了。 以下讀者可能也會像我一樣困惑。 我推薦了Axel Rauschmayer博士新出版的“ Speaking JavaScript ”一書:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.