javascript - Object.create 在数组属性上的奇怪行为

标签 javascript

当使用带有原型(prototype)对象的 Object.create() 创建新对象时,新对象似乎为数组属性保留了对原型(prototype)的引用。

示例代码

var obj = { color: ['white'], cat: 'Kitty', state: {}};
obj2 = Object.create(obj);
obj2.color.push('blue');
obj2.color.push('red');
obj2.color.push('yellow');
obj2.cat = 'Fluffy';
obj2.state = {complete: false};
console.log('obj2 color = ' + JSON.stringify(obj2.color) + ', obj2.cat = ' + obj2.cat + ', state = ' + JSON.stringify(obj2.state));
console.log('obj color = ' + JSON.stringify(obj.color) + ', obj.cat = ' + obj.cat + ', state = ' + JSON.stringify(obj.state));

结果

obj2 color = ["white","blue","red","yellow"], obj2.cat = Fluffy, state = {"complete":false}
obj color = ["white","blue","red","yellow"], obj.cat = Kitty, state = {}

新 obj2 中的字符串属性“cat”具有预期的行为,并且独立于原型(prototype)对象“obj”中的该属性。与对象属性“state”相同。

但是,在数组 'color' 上,当我更改数组时,它也会在原型(prototype)对象上发生更改!

这是用 Javascript 编写的吗?对于来自面向对象背景的我来说,这是完全出乎意料的。我认为这没有逻辑。数组有什么不同?

如果值类型(如字符串)的行为与对象属性不同,我什至可以看到一些逻辑,但它们不会(如本例所示)——但数组的行为不同。

最佳答案

对象属性的赋值:

obj.xyz = "hello world";

总是直接在目标对象上更新(必要时创建)属性。

但是,将值压入数组构成“对对象属性的赋值”。请注意,根据您的代码,

obj2.color = ["green"];

将直接在目标对象上创建一个新的“颜色”属性。

在声明中

obj2.color.push('blue');

“颜色”属性是在原型(prototype)对象的查找操作中找到的。然后,通过该对象引用(对原型(prototype)上“color”属性的引用),查找“push”属性。最终在 Array.prototype 对象上找到了它。然后将该值作为函数调用。该过程中没有任何内容涉及更新“o​​bj2”的属性值。

原型(prototype)上的“color”属性是一个数组并不是特别特别。对于任何对象引用,您都会看到类似的效果。考虑:

var proto = { obj: { a: 1, b: 2 } };
var obj2 = Object.create(proto);
obj2.obj.a = 3;

这将改变原型(prototype)中的“obj”对象。

最后应该注意的是,通常原型(prototype)是函数引用的来源,而不是简单的值。

关于javascript - Object.create 在数组属性上的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49557678/

相关文章:

javascript - 我如何制作这个简单的 JavaScript 函数?

javascript - 如何设置输入类型 ="number"的样式?

Javascript - 从文件上传创建 Canvas 图像元素

javascript - TypeError : this. form._updateTreeValidity 不是函数

javascript - 用孔填充区域

javascript - 使用 Jquery cookie 存储 div 的切换状态?

javascript - 在 Chrome 上执行多个选择器时 jQuery 中的 INVALID_NODE_TYPE_ERR

javascript - 使用 ControllerAs 语法的 Firebase 3 向数据绑定(bind)

javascript - 如何将数据传输到 ASP.NET MVC 中的 <div>

javascript - 使用 Javascript 在数组数组中搜索第一个索引