簡體   English   中英

修改孩子的原型會影響父母的原型嗎?

[英]Can modifying the prototype on a child affect the parent's prototype?

盡管這種下面的實現看起來不錯,因為它允許子代擁有自己的成員副本(不具有修改父代成員的能力),並且使用原型鏈,因此不會為每個對象實例創建屬性,它效率不高,因為調用了Parent構造函數兩次(一次適用於apply和新的Parent實例化):

function Parent(a,b,c,d){
  this.a = a;
  this.b = b;
  this.c = c;
  this.d = d;
}

Parent.prototype.say_a = function(){
  return this.a;
}

Parent.prototype.say_b = function(){
  return this.b;
}

Parent.prototype.say_c = function(){
  return this.c;
}

Parent.prototype.say_d = function(){
  return this.d;
}

Parent.prototype.not_going_to_be_copied = function(){
  console.log(“This function will not be recreated from one object instantiation to the next, making it very efficient.”);
}


function Child(a,b,c,d){
  Parent.apply(this,arguments);
}
Child.prototype = new Parent();
c = new Child("a","b","c","d");
console.log([c.say_a(),c.say_b(),c.say_c(),c.say_d()].join(" "));

Javascript Patterns中的Stoyan提到了該替代方法,它根本不調用Parent構造函數:

Child.prototype = Parent.prototype;

但是,他說這樣做的缺點是,如果繼承鏈中某個地方的一個孩子或孫子修改了原型,它將影響所有父母和祖父母。

但是,我無法復制該主張:

function Parent(){}

Parent.prototype.set_a = function(a){
  this.a = a;
}

Parent.prototype.get_a = function(){
  return this.a;
}

function Child(){}
Child.prototype = Parent.prototype;

var c = new Child();
var p = new Parent();
c.set_a("a");
console.log(c.get_a()); // a
p.set_a("b");
console.log(p.get_a()); // b
console.log(c.get_a()); // a
c.prototype = {};
console.log("after mod " + c.get_a()); // after mod a
console.log("after mod " + p.get_a()); // after mod b
c.get_a = function(){return "am I changing parent?"}
console.log(c.get_a()); // am I changing parent?
console.log(p.get_a()); // b

如您所見,無論我如何修改Child的原型,它都不會影響Parent的原型。 那我想念什么嗎? 孩子們對原型的修改會對父母產生影響嗎?

Child.prototype = Parent.prototype同一對象綁定到兩個構造函數的原型屬性(並且相當愚蠢,IMOHO)。 因此,修改被稱為Child.prototype的對象將修改Parent.prototype ,如所聲明的那樣“影響所有對象”,因為兩個表達式求值的對象都是相同的

考慮一下以后是否;

Child.prototype.hello = "Hello world"
// Noting that
Child.prototype === Parent.prototype  // -> true, as per initial condition

然后;

var p = new Parent()
p.hello                  // -> "Hello world", showing the "affecting" behavior    

因此可以看出,修改Child.prototype也會影響Parent實例的[prototype]-因為修改了同一對象

但是,此問題並未得到重現,因為無法以這種方式“分配實例的原型”。 也就是說,[prototype]鏈在創建新實例時根據構造函數的 prototype屬性設置(或通過Object.create設置)。 分配給實例的prototype屬性是..只是分配一個普通屬性。

var c = new Child()
c.prototype = "Hello world"
typeof c.say_a                   // -> "function", didn't assign [prototype]
c.prototype                      // -> "Hello world"
c.__proto__ === Child.prototype  // -> true, in browsers supporting __proto__
Child.prototype = Parent.prototype;

不好是因為如果孩子是狗,父母是動物,我們可以說狗是動物,但不能說動物是狗(蛇是什么?)。

這是哪里出了問題

var Animal=function(){};
var Snake = function(){};
Snake.prototype=Animal.prototype;
var Dog = function(){};
Dog.prototype=Animal.prototype;
Dog.prototype.bark=function(){console.log('I am barking');};

var aSnake = new Snake();
aSnake.bark();//I am barking ???

最好使用Object.crate來設置Child的原型,而不是將其設置為Parent的實例,因為Parent具有實例特定的成員,這些成員不應該位於Child上,並且您可能會遇到以下情況:Parent構造函數需要傳遞在以下情況下不可用的參數:聲明Child類型(這是錯誤的形式)。

在您的代碼中c.get_a隱藏了原型成員,並且不影響原型。 這將在此處詳細說明。

暫無
暫無

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

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