关于ecmascript 5:有没有理由在JavaScript中使用Object.create()或new?

Is there any reason to use Object.create() or new in JavaScript?

到目前为止,我一直在使用javascript中的new关键字。我一直在读关于Object.create的文章,不知道我是否应该用它来代替。我不太明白的是,我经常需要运行构造代码,所以我看不出Object.create是如何工作的,因为它不会触发任何运行函数。

有人能告诉我,在哪种情况下,我应该使用Object.create而不是new


到目前为止,如果要创建对象,则只能使用文本:

1
var obj = {};

Object构造函数。

1
var obj = Object();

但这些方法都不允许您指定所创建对象的原型。

这就是你现在可以用Object.create做的。它允许您创建一个新对象,并将第一个参数设置为新对象的原型。此外,它允许您设置作为第二个参数提供的新对象的属性。

它类似于这样做(没有第二个参数):

1
2
3
4
5
function create(proto) {
    var Constr = function(){};
    Constr.prototype = proto;
    return new Constr();
}

因此,如果您使用类似于此的构造,那么当您想要使用Object.create时,就需要这样做。

它不是new的替代品。它更能使创建应该从另一个对象继承的单个对象变得简单。

例子:

我有一个目标1(4):

1
2
3
var a = {
   someFunction: function() {}
};

我想让b扩展这个对象。然后可以使用Object.create

1
2
b = Object.create(a);
b.someOtherFunction = function(){};

只要您有一个构造器函数,但只从中实例化一个对象,就可以用Object.create替换它。

一般规则适用。这在很大程度上取决于构造函数的作用以及如何从其他对象继承等等。


太晚了。但我认为需要做的一个重要区别是,尽管构造函数只是函数,但新的操作符调用函数并捕获结果对象,这在动态环境中是有用的。它允许在构造函数执行期间引用属性和方法,根据具体情况,这些属性和方法可能有用,也可能不有用。如果您更关心拥有一个集合原型,但是对象本身比没有更静态,那么object.create将是一个更好的选择,因为它更干净,并且不会像新的操作符那样以意想不到的方式与原型链相混淆。

一些简单的例子……

1
2
3
4
5
6
7
8
9
var Foo = function(element) {
  this.elem = element;
  $(this.elem).css('color', 'blue');
  // using the new operator here gives access to this.elem
  // immediately after that declaration is made, thus providing
  // a comfortable dynamic system to work with
}

var bar = new Foo(someElem);

作为…

1
2
3
4
5
6
7
8
var foo = {
  elem : element,             // assume elem exists
  $(this.elem).css('color', 'blue')// in the lexical scope
}

var bar = Object.create(foo);
// This.elem does not exist until the object is returned now
// and the .css method call will not execute

应该更清楚一点,为什么你要用一个比另一个,作为另一个简单的分解…

当你想拥有一个动态的对象,而不是原型链时,使用new。

使用object.create时,您不太关心动态性,而更关心有一个明确的原型链。我还将注意到,使用object.create生成的对象也可以通过一个名为init的方法进行动态构建,您可以构建该方法来根据需要分配属性,并且只需对刚返回的对象调用它。

每种方法都有它的起伏,但是在我看来它们的用例是相当不同的。但是,您很可能会发现自己在使用object.create,因为大多数情况下都会调用一个不太动态的情况,并且需要更多的继承。


如前所述,当您需要一种简单的方法来设置新对象的原型时,通常使用EDCOX1(8)。然而,其他答案没有提及的是,构造函数(需要新的)与其他任何函数都不一样。

事实上,任何函数都可以返回一个对象,在JavaScript中常见的是查看工厂函数(比如构造函数,但是它们不需要EDCOX1×3),或者使用EDCOX1(10)来引用新对象。工厂函数经常使用EDCOX1〔8〕来设定新对象的原型。

1
2
3
4
5
6
7
8
9
var barPrototype = {
  open: function open() { /* ... */ },
  close: function close() { /* ... */ },
};
function createBar() {
  return Object.create(barPrototype);
}

var bar = createBar();

object.create()函数的确切源代码是:

1
2
3
4
5
6
7
8
9
10
11
12
13
function Object.Create(proto, propertiesObject)
{
    var obj = {};

    Object.setPrototypeOf(obj, proto);

    if(propertiesObject)
    {
        Object.defineProperties(obj, propertiesObject);
    }

    return obj;
}