为什么这个代码:
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 ..
我的第一个直觉是,因为在第一段代码中我们正在为bar分配一个foo引用,那么它意味着更改也将应用于foo,而在第二段代码中,它可能会从foo“继承”,并且因此bar的'子类'属性的变化赢了; t适用于它的'超类'(原型)..
有人可以确认我的假设至少在正确的轨道上吗?绝对会欣赏任何答案。提前谢谢。
答案 0 :(得分:13)
该行:
var bar = new Object( foo );
在你的第一个片段中,它没有做任何事情 - 你的假设是正确的 - 它只会返回对传递给Object
构造函数的同一个对象的引用。
当您将本机对象传递给Object
表达式(new Object(value)
)中的new
构造函数时,如果您传递{{3>结果是依赖于实现的。
如果您没有传递值(或者您明确传递基元undefined
或null
),则会创建一个继承自Object.prototype
的新对象。
否则,如果传递任何剩余的基元(作为数字,字符串或布尔值),将创建基元包装器对象(基本上是“基元到对象”类型转换),例如。
var s = new String("foo"); // a string object wrapper
typeof s; // "object"
s.valueOf(); // "foo"
请参阅有关基元和对象的问题:host object
在你的第二个片段中,行:
var bar = Object.create( foo );
创建一个新对象,它继承自foo
,并且因为它是一个不同的对象,所以在分配属性时:
bar.three = 3;
bar.one = 100;
这些将在分隔的实例上进行物理创建,如您所见,bar.one
属性阴影包含在foo
中的值。
bar
引用的对象实际上将包含两个自己的属性(one
和three
,但由于它继承自foo
,名为two
的属性可通过原型链解析,例如:
bar.hasOwnProperty('one'); // true, the property is "own"
bar.hasOwnProperty('two'); // false, the property is "inherited" from foo
bar.two; // 2, is accessible
基本上,bar
的原型链看起来像这样:
----------------- ========> | Object.prototype| ==> null | ----------------- |-------------| [[Prototype]] |---------| | one: 100 | ====================> | one: 1 | (shadowed) | three: 3 | | two: 2 | |-------------| |---------| (== line denotes the prototype chain)
答案 1 :(得分:2)
new Object
和Object.create
完全不同,尽管它们的名字相似。
new Object()
相当于一个空对象文字{}
,你应该总是使用它。使用参数,new Object(obj)
只返回参数。
Object.create(obj)
有助于解开JavaScript混乱的原型继承。阅读道格拉斯克罗克福德的this文章将有助于此。基本上,它创建了一个继承自obj
的新对象。所以,如果你有
var obj1 = {x: 1}, obj2 = Object.create(obj1);
obj1.x; // 1
obj2.x; // 1
obj2.x = 42;
obj1.x; // 1
obj1.x = 10;
obj2.x; // 10, since obj2 inherits from obj1, changing obj1's properties
// changes obj2, but not the other way around.