最近,我偶然发现了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()
使用的对象实际上形成了新对象的原型,而在声明的属性/函数中的new Function()
则没有形成原型。 - 您不能像使用功能语法那样使用
Object.create()
语法创建闭包。 给定JavaScript的词法(与代码块)类型范围,这是合乎逻辑的。
以上说法正确吗? 我想念什么吗? 您什么时候可以使用另一个?
编辑:链接到上述代码示例的jsfiddle版本: http : //jsfiddle.net/rZfYL/
#1楼
这是两个调用在内部执行的步骤:
(提示:唯一的区别在于步骤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
不执行构造函数。
#2楼
区别在于所谓的“伪古典与原型继承”。 建议在代码中仅使用一种类型,而不是将两种类型混合使用。
在伪古典继承中(使用“ new”运算符),假设您先定义一个伪类,然后从该类创建对象。 例如,定义一个伪类“ Person”,然后从“ Person”创建“ Alice”和“ Bob”。
在原型继承中(使用Object.create),您直接创建一个特定的人“ Alice”,然后使用“ Alice”作为原型创建另一个人“ Bob”。 这里没有“班级”; 都是对象。
在内部,JavaScript使用“原型继承”。 “伪古典”方式只是一些糖。
有关两种方法的比较,请参见此链接 。
#3楼
简而言之, new X
是Object.create(X.prototype)
,另外还要运行constructor
函数。 (并使constructor
有机会return
实际对象,该对象应该是表达式的结果而不是this
。)
而已。 :)
其余的答案只是令人困惑,因为显然没有其他人会读new
的定义。 ;)
#4楼
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)
#5楼
这个:
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()
的两个参数版本,则可以执行更强大的操作。
来源:oschina
链接:https://my.oschina.net/u/3797416/blog/3168437