了解Object.create()和new SomeFunction()之间的区别

北城余情 提交于 2020-02-27 04:58:30

最近,我偶然发现了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()

  1. 创建new Object() obj
  2. 设置obj.__proto__Test.prototype
  3. return Test.call(obj) || obj; // normally obj is returned but constructors in JS can return a value

Object.create( Test.prototype )

  1. 创建new Object() obj
  2. 设置obj.__proto__Test.prototype
  3. return obj;

因此,基本上Object.create不执行构造函数。


#2楼

区别在于所谓的“伪古典与原型继承”。 建议在代码中仅使用一种类型,而不是将两种类型混合使用。

在伪古典继承中(使用“ new”运算符),假设您先定义一个伪类,然后从该类创建对象。 例如,定义一个伪类“ Person”,然后从“ Person”创建“ Alice”和“ Bob”。

在原型继承中(使用Object.create),您直接创建一个特定的人“ Alice”,然后使用“ Alice”作为原型创建另一个人“ Bob”。 这里没有“班级”; 都是对象。

在内部,JavaScript使用“原型继承”。 “伪古典”方式只是一些糖。

有关两种方法的比较,请参见此链接


#3楼

简而言之, new XObject.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()的两个参数版本,则可以执行更强大的操作。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!