new Object() 和 Object.create() 创建对象有什么不同之处,先看一个例子:
var foo = {
something: function() {
console.log( "Tell me something good..." );
}
};
foo.c = 1
var a = Object.create( foo );
var b = new Object(foo)
foo.foo='foo'
a.a='a'
b.b = 'b'
b.something()
a.something(); // Tell me something good...
console.log('a:',a)
console.log('b:',b)
console.log('foo:',foo)
打印结果:
b.something(); //Tell me something good…
a.something(); // Tell me something good…
console.log(‘a:’,a) // a: {a: “a”}
console.log(‘b:’,b) //b: {c: 1, foo: “foo”, b: “b”, something: ƒ}
console.log(‘foo:’,foo) //foo: {c: 1, foo: “foo”, b: “b”, something: ƒ}
发现:
在控制台上打印,看出这两种创建对象区别,十分清晰,create创建的对象只是原型指向foo,之后它俩无任何关系了,无论foo怎么修改,都不会影响a,a添加属性也不会影响foo,new 方式则会相互影响
扩展
当要设计通用组件或模块时,假设要调用 a.something(),如果 a中不存在 something()
时这条语句也可以正常工作的话,那你的 API 设计就会变得很“神奇”,对于未来维护你
者来说这可能不太好理解。
但是你可以让你的 API 设计不那么“神奇”,同时仍然能发挥 [[Prototype]] 关联的威力:
var foo= {
something: function() {
console.log( "something!" );
}
};
var a= Object.create(foo);
a.doSomething= function() {
this.something(); // 内部委托!
};
a.doSomething(); // "something!"
这里我们调用的 a.doSomething() 是实际存在于 a中的,这可以让我们的 API 设计更加清晰(不那么“神奇”)。从内部来说,我们的实现遵循的是委托设计模式,通过 [[Prototype]] 委托到foo.something()。
小结:
Object.create(…) 会创建一个新对象(bar)并把它关联到我们指定的对象(foo),这样 我们就可以充分发挥 [[Prototype]] 机制的威力(委托)并且避免不必要的麻烦(比如使 用 new 的构造函数调用会生成 .prototype 和 .constructor 引用)。。create()则不会生成这些引用,避免一些不必要的麻烦