理解Object.create()和新SomeFunction()之间的区别
我最近偶然发现了JavaScript中的Object.create()
方法,并试图推断它与用new SomeFunction()
创建对象的新实例的方式不同,以及何时想要使用另一个方法。
考虑下面的例子:
var test = {
val: 1,
func: function() {
return this.val;
}
};
var testA = Object.create(test);
testA.val = 2;
console.log(test.func()); // 1
console.log(testA.func()); // 2
console.log('other test');
var otherTest = function() {
this.val = 1;
this.func = function() {
return this.val;
};
};
var otherTestA = new otherTest();
var otherTestB = new otherTest();
otherTestB.val = 2;
console.log(otherTestA.val); // 1
console.log(otherTestB.val); // 2
console.log(otherTestA.func()); // 1
console.log(otherTestB.func()); // 2
Object.create中使用的对象实际上形成了新对象的原型,在新的Function()形式中,声明的属性/函数不构成原型。
是的, Object.create
构建一个直接从作为其第一个参数传递的对象继承的对象。
使用构造函数,新创建的对象从构造函数的原型继承,例如:
var o = new SomeConstructor();
在上面的例子中, o
直接从SomeConstructor.prototype
继承。
这里有一个区别,用Object.create
你可以创建一个不会从任何东西继承的对象, Object.create(null);
另一方面,如果你设置SomeConstructor.prototype = null;
新创建的对象将从Object.prototype
继承。
您不能像使用函数语法那样使用Object.create语法创建闭包。 鉴于JavaScript的词法(vs block)类型,这是合乎逻辑的。
那么,你可以创建闭包,例如使用属性描述符参数:
var o = Object.create({inherited: 1}, {
foo: {
get: (function () { // a closure
var closured = 'foo';
return function () {
return closured+'bar';
};
})()
}
});
o.foo; // "foobar"
请注意,我正在讨论ECMAScript第5版Object.create
方法,而不是Crockford的垫片。
该方法开始在最新的浏览器上本地实现,请检查此兼容性表。
很简单地说, new X
是Object.create(X.prototype)
,另外运行constructor
函数。 (并给予constructor
return
应该是表达式结果的实际对象的机会,而不是this
。)
而已。 :)
其余的答案只是令人困惑,因为显然没有人读到new
的定义。 ;)
以下是两个呼叫在内部发生的步骤:
(提示:唯一的区别是在步骤3)
new Test()
:
new Object()
obj obj.__proto__
到Test.prototype
return Test.call(obj) || obj; // normally obj is returned but constructors in JS can return a value
Object.create( Test.prototype )
new Object()
obj obj.__proto__
到Test.prototype
return obj;
所以基本上Object.create
不会执行构造函数。
上一篇: Understanding the difference between Object.create() and new SomeFunction()