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

我今天发现了一些非常奇怪的东西:如果用构造函数和new关键字创build对象,但是从构造函数return一个函数,则它的行为如下所示:

  1. 新创build的“对象”是一个function。
  2. 那个新的函数可以像正常一样调用,但是…
  3. 如果在构造函数中维护this引用,则会引用从构造函数正确创build的对象。 这是你期望new回报。

这是一个例子:

 function Constructor() { var self = this; this.name = 'instance'; return function() { return self; } } 

所以,如果你像这样实例化: var instance = new Constructor()以下将会导致:

 typeof instance //returns "function" typeof instance() //returns "object" instance() //returns { name: 'instance' } 

所以我想我有三个问题:

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

  1. 是的,虽然构造函数默认返回正在构造的新对象(由此引用) ,但只要返回对象 ,就可以覆盖该返回值。 因为函数是一个对象,所以你可以按照你的例子返回它。 新创build的对象本身不是一个函数,但是你的返回函数在variables作用域中引用了新创build的对象。

  2. 见#1

  3. 这是因为一个函数创build一个闭包,所以它继续引用selfvariables,这恰好引用正在构build的实际对象。 所以我不会说这是“内部”的东西,而只是function的variables范围的一部分。

要理解的是,你的function没有任何其他function不同。 就像如果你有一个返回一个数组,你只是有一个规则的数组,可以引用新的对象。

 function Constructor() { this.name = 'instance'; return [ this ]; // Instead return an Array that references the new object } 

那么这是一个非常好的问题,正如你可能猜到的那样,不容易回答。

说得很简单:
1)是和是; 这是您在“传统”编程语言中找不到的神奇function之一。
2)请阅读closures(下面的链接)
3)是(请阅读更多)

您应该阅读更多关于Javascript闭包: http : //jibbering.com/faq/notes/closures/
http://www.javascriptkit.com/javatutors/closures.shtml (这里有一些很好的例子)

更具体地说,寄生虫遗传模型:
http://blog.higher-order.net/2008/02/21/javascript-parasitic-inheritance-power-constructors-and-instanceof/

我希望这有帮助

这就是你所说的封闭

它所做的是创build一个独立的代码环境(通常称为对象)

 typeof instance //returns "function" - since it's not "fired" or called. just returns the function declaration (correct me if i'm wrong) typeof instance() //returns "object" - it returns an object since you called it instance() //returns an object also - you called it, but you didn't store it 

使用闭包构build的对象的示例:

 function Constructor() { var privateProperty = 'private'; var privateMethod = function(){ alert('called from public method'); }; //return only what's to be seen in public return { publicProperty: 'im public', publicMethod: function(){ alert('called from public method'); } getter: privateMethod //assign to call the private method } } var myObj = Constructor(); var pubProp = myObj.publicProperty; // pubProp = 'im public' myObj.publicMethod() //alert: 'called from public method'; myObj.getter() //alert: 'called from public method'; //cannot access since "private": myObj.privateProperty myObj.privateMethod