我一直在試驗原型繼承,如下面的代碼片段所示。在父級原型上設置屬性
function extend(c, p) {
function f() { this.constructor = c; }
f.prototype = p.prototype;
c.prototype = new f();
}
function Parent() {}
function Child() {}
extend(Child, Parent);
var p = new Parent();
var c = new Child();
// Child.prototype.say = function() { alert("child"); };
Parent.prototype.say = function() { alert("parent"); };
p.say();
c.say();
運行此腳本時,會顯示兩條警報顯示parent
。
但是,如果我取消對註釋行的註釋,則第一個警報顯示parent
,而第二個顯示child
。
乍一看,這是非常意外的。看起來Parent.say
將覆蓋Child.say
,因爲它稍後設置。
從我的理解,因爲Child.prototype
是一個對象,而f
一個實例,在這個原型設置的所有屬性上直接設置的f
該特定實例的實例。
當調用c.say
,將發生以下情況:
如果
say
直接設置c
,調用它。它不會直接在實例上設置,因此,請跳至2.在
Children.prototype
中查找say
,f
的實例。再次查找直接在f
實例上設置的屬性。如果該行是未註釋,則在此處找到say
,並停止搜索。查找
say
在f.prototype
,這是Parent.prototype
。這是發現say
的地方,當時線路仍然爲評論了。
問:我才明白正確的JavaScript如何查找財產?如果是這種情況,那麼可以解釋爲什麼子行不是,如果該行未被註釋,則由父屬性重寫。
有道理。現有實例受到影響的原因是實例的原型和構造函數的原型仍然保持相同的對象。 – afsantos
@afsantos:對,它們都指向同一個對象,因此通過這兩個引用向該對象添加屬性。 –
非常棒的答案!對於ASCII藝術的獎勵點,應該有一個工具來自動說明這些事情。 – afsantos