最近,我偶然发现了JavaScript中的Object.create()
方法,并试图推断出它与使用new SomeFunction()
建立对象的新实例有何不一样,以及什么时候要在另外一个对象上使用它。 闭包
考虑如下示例: ide
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()
使用的对象实际上造成了新对象的原型,而在声明的属性/函数中的new Function()
则没有造成原型。 Object.create()
语法建立闭包。 给定JavaScript的词法(与代码块)类型范围,这是合乎逻辑的。 以上说法正确吗? 我想念什么吗? 您何时可使用另外一个? this
编辑:连接到上述代码示例的jsfiddle版本: http : //jsfiddle.net/rZfYL/ spa
这是两个调用在内部执行的步骤:
(提示:惟一的区别在于步骤3) .net
new Test()
: prototype
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 )
code
new Object()
obj obj.__proto__
到Test.prototype
return obj;
所以,基本上Object.create
不执行构造函数。 orm
区别在于所谓的“伪古典与原型继承”。 建议在代码中仅使用一种类型,而不是将两种类型混合使用。 对象
在伪古典继承中(使用“ new”运算符),假设您先定义一个伪类,而后从该类建立对象。 例如,定义一个伪类“ Person”,而后从“ Person”建立“ Alice”和“ Bob”。
在原型继承中(使用Object.create),您直接建立一个特定的人“ Alice”,而后使用“ Alice”做为原型建立另外一我的“ Bob”。 这里没有“班级”; 都是对象。
在内部,JavaScript使用“原型继承”。 “伪古典”方式只是一些糖。
有关两种方法的比较,请参见此连接 。
简而言之, new X
是Object.create(X.prototype)
,另外还要运行constructor
函数。 (并使constructor
有机会return
实际对象,该对象应该是表达式的结果而不是this
。)
而已。 :)
其他的答案只是使人困惑,由于显然没有其余人会读new
的定义。 ;)
function Test(){ this.prop1 = 'prop1'; this.prop2 = 'prop2'; this.func1 = function(){ return this.prop1 + this.prop2; } }; Test.prototype.protoProp1 = 'protoProp1'; Test.prototype.protoProp2 = 'protoProp2'; var newKeywordTest = new Test(); var objectCreateTest = Object.create(Test.prototype); /* Object.create */ console.log(objectCreateTest.prop1); // undefined console.log(objectCreateTest.protoProp1); // protoProp1 console.log(objectCreateTest.__proto__.protoProp1); // protoProp1 /* new */ console.log(newKeywordTest.prop1); // prop1 console.log(newKeywordTest.__proto__.protoProp1); // protoProp1
摘要:
1)使用new
关键字须要注意两点;
a)函数用做构造函数
b)将function.prototype
对象传递给__proto__
属性...或不支持__proto__
的地方,它是新对象查找属性的第二个位置
2)使用Object.create(obj.prototype)
构造一个对象( obj.prototype
)并将其传递给预期的对象..区别在于如今新对象的__proto__
也指向obj.prototype(请参考xj9)
这个:
var foo = new Foo();
和
var foo = Object.create(Foo.prototype);
很是类似。 一个重要的区别是, new Foo
实际上运行构造函数代码,而Object.create
将不会执行诸如
function Foo() { alert("This constructor does not run with Object.create"); }
请注意,若是您使用Object.create()
的两个参数版本,则能够执行更强大的操做。