javascript - 修改 child 的原型(prototype)会影响 parent 的原型(prototype)吗?

标签 javascript

虽然下面的实现看起来不错,因为它允许子级拥有自己成员的副本(没有能力修改父级自己的成员),而且它使用原型(prototype)链,所以不会为每个子级重新创建属性对象实例化,效率不高,因为 Parent 构造函数被调用两次(一次用于 apply 和 new 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(" "));

Stoyan 在 Javascript Patterns 中提到了这个替代方案,它根本不调用 Parent 构造函数:

Child.prototype = Parent.prototype;

但是,他说这样做的一个缺点是,如果继承链下游某处的一个 child 或孙子修改了原型(prototype),它会影响所有的 parent 和祖 parent 。

但是,我无法重现该声明:

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的原型(prototype),都不会影响Parent的原型(prototype)。那我错过了什么吗? child 对原型(prototype)的修改会影响到家长吗?

最佳答案

Child.prototype = Parent.prototype 之后,相同的对象 被绑定(bind)到两个构造函数的原型(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] 链基于构造函数的原型(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__

关于javascript - 修改 child 的原型(prototype)会影响 parent 的原型(prototype)吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25588255/

相关文章:

javascript - 从动态创建的 li 中获取值(value)

javascript - JavaScript 函数没有返回值

javascript - 使用 Bootstrap 时间选择器时,data-ng-model 值不会更新

javascript - 如何在 karma 测试中设置 Tealium-Angular 配置

javascript - Angular 错误 : [$rootScope:inprog] $apply already in progress on document. click()

javascript - 如何从loopback API获取当前用户的数据?

javascript - Javascript (ES6) 中的静态变量继承

javascript - window.open 操作

Javascript onkeypress 事件触发但输入的文本值不正确

javascript - 如何模拟外部模块方法?