为什么是这段代码:
var foo = {one: 1, two: 2};
var bar = new Object( foo );
bar.three = 3;
bar.one = 100;
document.write(bar.one); //100
document.write(foo.one); //100
导致 bar.one 和 foo.one 都是 100,而
var foo = {one: 1, two: 2};
var bar = Object.create( foo );
bar.three = 3;
bar.one = 100;
document.write(bar.one); //100
document.write(foo.one); //1
只影响 bar.one..
我的第一直觉是,由于在第一段代码中我们将 foo 引用分配给 bar,这意味着更改也将应用于 foo,而在第二段代码中,它可能“继承”自 foo,并且因此,bar 的“子类”属性的更改不会应用于其“父类(super class)”(原型(prototype))..
有人可以确认我的假设至少是正确的吗?非常感谢任何答案。提前致谢。
最佳答案
行:
var bar = new Object( foo );
在您的第一个片段中,它什么都不做——您的假设是正确的——它只会返回对传递给 Object
的同一对象的引用。构造函数。
这就是将本地对象 传递给 Object
时的行为new
中的构造函数表达式 ( new Object(value)
),如果你传递一个 host object ,结果取决于实现。
如果您不传递一个值(或者您显式传递原语 undefined
或 null
)一个继承自 Object.prototype
的新对象将被创建。
否则,如果您传递任何剩余的基元(作为数字、字符串或 bool 值),将创建一个基元包装对象(基本上是“基元到对象”类型转换),例如。
var s = new String("foo"); // a string object wrapper
typeof s; // "object"
s.valueOf(); // "foo"
请参阅有关基元和对象的问题:How is a Javascript string not an object?
在您的第二个代码段中,行:
var bar = Object.create( foo );
创建一个继承自 foo
的新对象, 因为它是一个不同的对象,所以当您分配属性时:
bar.three = 3;
bar.one = 100;
那些将在分离的实例上物理创建,如您所见,bar.one
属性 shadows foo
中包含的值.
bar
引用的对象,实际上将包含两个自己的属性( one
和 three
,但由于它继承自 foo
,名为 two
的属性可通过原型(prototype)链解析,例如:
bar.hasOwnProperty('one'); // true, the property is "own"
bar.hasOwnProperty('two'); // false, the property is "inherited" from foo
bar.two; // 2, is accessible
基本上,bar
的原型(prototype)链看起来像这样:
----------------- ========> | Object.prototype| ==> null | ----------------- |-------------| [[Prototype]] |---------| | one: 100 | ====================> | one: 1 | (shadowed) | three: 3 | | two: 2 | |-------------| |---------| (== line denotes the prototype chain)
关于javascript - Object.create(foo) 和 new Object(foo) 的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6970242/