【问题标题】:What does the new keyword do under the hood?new 关键字在幕后做了什么?
【发布时间】:2011-04-08 17:32:37
【问题描述】:

我很好奇 new 关键字在后台除了更改 this 范围所指的内容之外还有什么作用。

例如,如果我们比较使用new 关键字让函数在对象上设置属性和方法与仅让函数返回一个新对象,那么新对象有什么额外的功能吗?

如果我不希望从函数构造函数创建多个对象,这是首选

var foo2 = function () {
  var temp = "test";

  return {
    getLol: function () {
      return temp;
    },

    setLol: function(value) {
      temp = value;
    }
  };

}();

var foo = new function () {
  var temp = "test";

  this.getLol = function () {
    return temp;
  }

  this.setLol = function(value) {
    temp = value;
  }
}();

萤火虫探查器告诉我使用 new 关键字稍快(2ms 而不是 3ms),在大型对象上 new 仍然明显更快?

[编辑]

另一个问题是关于真正大的对象构造函数是在函数底部有一个返回(它将有大量的本地函数)或者在函数的顶部有一些 this.bar = ...可读?什么是好的约定?

var MAIN = newfunction() {
    this.bar = ...

    // Lots of code
}();

var MAIN2  = function() {
    // Lots of code

    return {
        bar: ...
    }
}();

【问题讨论】:

标签: javascript oop prototype object new-operator


【解决方案1】:

the Good Parts book(第47页)引用Douglas Crockford来回答这个问题的标题:

如果new 运算符是一个方法而不是一个运算符,它可以这样实现:

Function.method('new', function () {

   // Create a new object that inherits from the 
   // constructor's prototype.

   var that = Object.create(this.prototype);

   // Invoke the constructor, binding -this- to
   // the new object.

   var other = this.apply(that, arguments);

   // If its return value isn't an object,
   // substitute the new object.

   return (typeof other === 'object' && other) || that;
});

Function.method 方法实现如下。这将实例方法添加到类 (Source):

Function.prototype.method = function (name, func) {
   this.prototype[name] = func;
   return this;
};

进一步阅读:

【讨论】:

  • 现在我只需要弄清楚 this.prototype、th​​is.apply 和 Function.method 在内部做什么:)。有时我觉得我应该更多地假设和破解,并尝试更少地了解内部。
  • @Raynos: Function.method 不是内置方法。添加了一些关于此的更多信息。
  • 谢谢,我以后会花一些时间阅读这些内容。仍然掌握原型设计的窍门。
  • 看来Crockford先生忘记了函数也是对象嘿嘿(如果other是函数,它仍然会返回that
  • @CMS:构造函数只会在用new Function()构造函数时返回一个函数,对吧?在这种情况下,上述方法将不起作用,除非我们也检查 typeof other === 'function'。是这样吗,还是我错过了什么?
【解决方案2】:

阅读the spec11.2.213.2.2 部分是相关的,并且不太难理解(请注意,后两个链接指向规范的非官方 HTML 化版本)。

总之,如果你有一个返回对象的函数f,那么使用new 调用它的唯一可观察到的区别是this 的值将不同,而使用@987654327 调用它@ 可能会更慢,因为它涉及创建对象并为其分配一些属性的额外步骤。

【讨论】:

  • 听起来new 是反模式吗?我想知道为什么对象根本需要new。让它看起来更像 Java/C++?
  • @thomson-comer 这不是反模式,它为对象提供了自己的this 变量
猜你喜欢
  • 1970-01-01
  • 2016-07-04
  • 1970-01-01
  • 1970-01-01
  • 2020-05-21
  • 2019-05-21
  • 2016-03-19
  • 1970-01-01
相关资源
最近更新 更多