JS prototype objects not inherited?

跟風遠走 提交于 2019-12-12 16:19:09

问题


My question is about a strange output that I came across while playing with JS prototypal inheritance.

Please take a look:

function Parent(){
}

Parent.prototype = {
  variable : 'a'
}; 


function Child(){
}

Child.prototype = new Parent();


child = new Child();

Parent.prototype =
{
  variable : 'c'
};


console.log(child.variable);  // output a
console.log(child.__proto__);  // [object Object] { variable: 'a'}

Why the child did not inherit property?

Of course if I would do this this way:

function Parent(){
}

Parent.prototype.variable = 'a'; 


function Child(){
}

Child.prototype = new Parent();


child = new Child();

Parent.prototype.variable = 'c';

console.log(child.variable); //  "c"
console.log(child.__proto__); //  [object Object] { variable: "c"}

The output is expected: "c" and

[object Object] {
  variable: "c"
}

does anyone know why the object 'prototype' is not beeing inherited while a normal property of 'prototype' is?


回答1:


Why the child did not inherit property?

difference between re assigning and mutating

re assigning:

var org = {val:22};
var copy = org;
//re assigning org de references copy
//  before this line copy === org
//  but after this line it isn't
org = {val:44};
//what do you think the value of copy is
console.log(copy.val);//=22 re assigning org de references copy

mutating:

var org = {val:22};
var copy = org;
org.val=33;//mutating org
//mutating copy (copy.val=11) would affect org
//  because org and copy are still the same (copy === org)
console.log(copy.val);//=33 because mutated org

You should not create an instance of Parent to set the prototype of Child (use Object.create instead) and in your comments you set the prototype of Child to be Parent.prototype, you can't do that because a Child is a Parent but a Parent isn't a Child (for example: a Dog is an Animal but an Animal is not a Dog because Animal could be a Snake).

More on constructor functions and prototype can be found here: https://stackoverflow.com/a/16063711/1641941




回答2:


Child.prototype = new Parent(); will construct a new Parent-object with the current Parent.prototype object as Child.prototype.__proto__.

Using: Parent.prototype.variable = 'c'; will change the objects property variable, since it is still the same object as of Child.prototype.__proto__, the variable will be modified on Child too.

Since Parent.prototype = { variable: 'c' }; will change the Parent.prototype object, to a completely new object. But the reference of the old prototype (Child.prototype.__proto__ will still remain the old, there will be no modification.




回答3:


does anyone know why the object 'prototype' is not beeing inherited …

Instances are assigned a private [[Prototype]] that is the the public prototype of their constructor when they are created. Assigning a new object to the constructor's prototype later doesn't change the [[Prototype]] of instances that have already been created, they continue to reference the original object.

So when you first construct child, it's [[Prototype]] is Child.prototype, which is an instance of Parent and therefore inherits from the Parent.prototype that existed when it was created.

When you later assign a new Parent.prototype, that doesn't change the [[Prototype]] of instances that have already been created, so Child.prototype still inherits from the original Parent.prototype, and hence child does too.

… while a normal property of 'prototype' is?

Because that just adds a new property to the existing object, it doesn't assign a new object to the prototype property of the constructor.



来源:https://stackoverflow.com/questions/23970431/js-prototype-objects-not-inherited

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!