【问题标题】:Is there any reason to use Object.create() or new in JavaScript?有什么理由在 JavaScript 中使用 Object.create() 或 new 吗?
【发布时间】:2011-07-07 15:41:09
【问题描述】:

到目前为止,我一直在 JavaScript 中使用 new 关键字。我一直在阅读有关Object.create 的信息,我想知道是否应该改用它。我不太明白的是我经常需要运行构造代码,所以我根本看不到Object.create 将如何工作,因为它不会触发任何函数运行。

谁能告诉我,在什么情况下我应该使用Object.create 而不是new

【问题讨论】:

标签: javascript ecmascript-5 object-create


【解决方案1】:

到目前为止,如果要创建对象,只能使用字面量:

var obj = {};

Object 构造函数。

var obj = Object();

但是这些方法都不能让你指定创建对象的原型

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

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

function create(proto) {
    var Constr = function(){};
    Constr.prototype = proto;
    return new Constr();
}

因此,如果您使用与此类似的构造,则当您想使用 Object.create 时。

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

例子:

我有一个对象a

var a = {
   someFunction: function() {}
};

我希望b 扩展这个对象。然后你可以使用Object.create:

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

只要你有一个构造函数,但你只从它实例化一个对象,你也许可以用Object.create替换它。

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

【讨论】:

  • 也许我很密集,但我还是不明白你什么时候会使用 Object.create 和 new?您能否给出一个使用 Object.create 的代码示例并解释为什么 new 不起作用?
  • @jfriend00:如果构造函数的唯一目的是创建一个从另一个对象继承的空对象,您将使用Object.create
  • 这有帮助,谢谢。在我看来,它是 YUI extend() 的语言支持版本,用于创建继承另一个对象原型的新对象。对吗?
【解决方案2】:

如前所述,Object.create() 通常用于您想要一种简单的方法来设置新对象的原型。不过,其他答案没有提到的是,构造函数(需要 new)与任何其他函数并没有什么不同。

事实上,任何函数都可以返回一个对象,在 JavaScript 中很常见看到工厂函数(像构造函数,但它们不需要new,或者使用this 来引用新对象)。工厂函数经常使用Object.create()来设置新对象的原型。

var barPrototype = {
  open: function open() { /* ... */ },
  close: function close() { /* ... */ },
};
function createBar() {
  return Object.create(barPrototype);
}

var bar = createBar();

【讨论】:

    【解决方案3】:

    这个线程太晚了.. 但我认为需要做出的一个重要区别是,虽然构造函数只是函数,但 new 运算符会调用函数并捕获生成的对象,这在动态环境中很有用。它还允许在执行构造函数期间引用属性和方法,这取决于具体情况可能有用也可能没用。如果您更关心设置原型但对象本身更静态,那么 Object.create 将是一个更好的选择,因为它更干净并且不会像 new 运算符那样以意想不到的方式混淆原型链.

    一些简单的例子..

    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);
    

    相对于..

    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,因为大多数情况都需要较少动态的情况,并且更需要继承。

    【讨论】:

      【解决方案4】:

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

      function Object.Create(proto, propertiesObject)
      {
          var obj = {};
      
          Object.setPrototypeOf(obj, proto);
      
          if(propertiesObject)
          {
              Object.defineProperties(obj, propertiesObject);
          }
      
          return obj;
      }
      

      【讨论】:

        猜你喜欢
        • 2014-03-11
        • 2012-10-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多