Object.create(foo)和new Object(foo)之间的区别?

时间:2011-08-07 02:01:49

标签: javascript

为什么这个代码:

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适用于它的'超类'(原型)..

有人可以确认我的假设至少在正确的轨道上吗?绝对会欣赏任何答案。提前谢谢。

2 个答案:

答案 0 :(得分:13)

该行:

var bar = new Object( foo );

在你的第一个片段中,它没有做任何事情 - 你的假设是正确的 - 它只会返回对传递给Object构造函数的同一个对象的引用。

当您将本机对象传递给Object表达式(new Object(value))中的new构造函数时,如果您传递{{3>结果是依赖于实现的。

如果您没有传递值(或者您明确传递基元undefinednull),则会创建一个继承自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引用的对象实际上将包含两个自己的属性onethree,但由于它继承自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 ObjectObject.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.