使用'new'创建对象时使用'return'

Kev*_*gue 10 javascript node.js

我今天发现了一些非常奇怪的事情:如果使用构造函数和new关键字创建对象,但是return构造函数中的函数,它的行为如下:

  1. 新创建的"对象"是一个函数.
  2. 可以像平常一样调用新函数,但是......
  3. 如果this在构造函数中维护引用,则this引用从构造函数正确创建的对象.这是你期望从中返回的new.

这是一个例子:

function Constructor() {
  var self = this;

  this.name = 'instance';
  return function() {
    return self;
  }
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您像这样实例化:var instance = new Constructor() 将产生以下结果:

typeof instance    //returns "function"
typeof instance()  //returns "object"
instance()         //returns { name: 'instance' }
Run Code Online (Sandbox Code Playgroud)

所以我猜我有三个问题:

  1. 这是合法的,它是否跨浏览器工作?它真的很棒,我认为它可以在很多方面使用,但这种行为是否可靠?
  2. 导致此行为的后台会发生什么?
  3. (可能由2回答,但是......)新实例中是否有新对象(以'this'引用的对象),所以它都是自包含的并且被垃圾收集器正确清理了?

小智 7

  1. 是的,虽然构造函数默认返回正在构造的新对象(由其引用this),但只要返回对象,就可以覆盖该返回值.因为函数是一个对象,所以您可以像在示例中一样返回它.新创建的对象本身不是函数,但返回的函数在其变量作用域中引用新创建的对象.

  2. 见#1

  3. 这是因为函数创建了一个闭包,因此它继续引用self变量,该变量恰好引用了正在构造的实际对象.所以我不会说它在"内部"任何东西,而只是函数变量范围的一部分.

要理解的是,您的功能与任何其他功能没有任何不同.就像你已经返回一个数组一样,你只需要一个可以引用新对象的常规数组.

function Constructor() {

  this.name = 'instance';
  return [ this ];  // Instead return an Array that references the new object
}
Run Code Online (Sandbox Code Playgroud)

  • @KevinMcTigue:嗯,所有函数都是闭包.它只是JavaScript中函数内部实现的一部分.使函数成为闭包的原因是它具有对创建它的原始变量作用域的永久引用.所以你只是返回一个普通的旧函数,它的行为与任何其他函数一样,因为它不会忽略它的变量范围*(包括`self`变量,它引用你的新对象)*. (2认同)