javascript - 原型(prototype)对象可以从实例更改

标签 javascript inheritance prototype-programming

有人可以用合理的方式向我解释一下吗:

function One() {}

One.prototype.obj = { key: 'value' };
One.prototype.str = 'string';

var inst1 = new One(),
    inst2 = new One();

// now let’s change some things in our second instance

inst2.obj.key = 'buh!';
inst2.str = 'buh!';

// ok, so what happens to our other instance?

console.log( inst1.str ); // Yields 'string' (unaffected, expected)
console.log( inst1.obj.key ); // Yields 'buh!' (!!)

console.log( One.prototype.obj.key ); // is also 'buh!'

看起来,如果原型(prototype)包含一个对象,那么您使用 new 关键字创建的实例就有该对象,但是如果您更改它,您也会更改原型(prototype)对象,从而影响所有实例,就像 sibling 继承模式...

这是它应该的工作方式吗?

最佳答案

实际上,Javascript 不会从原型(prototype)中复制任何内容。您在原型(prototype)上定义的所有内容仅存在一次(在原型(prototype)本身上)并被重用,因为相同的原型(prototype)实例被传递给所有对象。

当您访问对象的属性时,该对象会检查该属性是否已在其自身上定义。如果是,它将返回与该属性关联的值。如果不是,它将把调用委托(delegate)给它的原型(prototype),从现在起原型(prototype)将负责发生的事情。这就是为什么 Javascript 中的“继承”(代码重用)更适合称为委托(delegate)。

写访问的情况有点不同。如果您在对象上设置属性,它将在本地“隐藏”该值。这就是 str 属性不受影响的原因,它实际上是在 inst2 对象上定义的。但是,如果您删除 inst2.str 并执行另一个 console.log( inst2.str ),您会注意到它将返回旧值。

PS: 如果您想要一种方法来防止这种情况发生,请查看本教程:http://kevlindev.com/tutorials/javascript/inheritance/index.htm

我建议阅读整篇文章,但如果您只想了解内容,请参阅“创建子类”部分中的 KevLinDev.extend 函数。

关于javascript - 原型(prototype)对象可以从实例更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7622450/

相关文章:

javascript - 如何使用一个默认条件对 3 个条件执行三元语句

javascript - 为什么我的 xml 出现未定义错误?

java - java中的 "extends"和 "implements"在性能和内存等方面有什么区别

javascript - 对 javascript 的构造函数和原型(prototype)感到困惑?

javascript - 在构造函数中向原型(prototype)添加属性

javascript - Node JS 浏览器模拟(cookies、session、headers)

javascript - 类型错误 : Expected throat size to be a number but got undefined

Android:xml中组件的继承

c# - EF 6 使用 TPT 报错都具有相同的主键值

javascript - 原型(prototype)和对象创建