我今天发现了一些非常奇怪的东西:如果使用构造函数和new
关键字创建对象,但return
是构造函数中的函数,则其行为如下:
this
的引用,this
引用从构造函数正确创建的对象。这是您期望从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' }
所以我猜我有三个问题:
答案 0 :(得分:7)
是的,虽然构造函数默认返回正在构造的新对象(由this
引用),但您可以覆盖该返回值,只要你返回一个对象。因为函数是一个对象,所以您可以像在示例中一样返回它。新创建的对象不函数本身,但返回的函数在其变量范围内引用新创建的对象。
参见#1
这是因为函数创建了一个闭包,因此它继续引用self
变量,该变量恰好引用了正在构造的实际对象。所以我不会说它是“内部”任何东西,而只是函数变量范围的一部分。
要理解的是,您的功能与任何其他功能没有任何不同。就像你已经返回一个数组一样,你只需要一个可以引用新对象的常规数组。
function Constructor() {
this.name = 'instance';
return [ this ]; // Instead return an Array that references the new object
}
答案 1 :(得分:2)
嗯,这是一个非常好的问题,正如你可能已经猜到的那样,不容易回答。
简单地说:
1)是和是;这是“传统”编程语言中没有的令人惊叹的功能之一
2)请阅读关闭(下面的链接)
3)是(请阅读更多)
您应该阅读有关Javascript Closures的更多信息:
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/
我希望这会有所帮助
答案 2 :(得分:1)
这就是你所说的closure
它的作用是创建一个独立的代码环境(通常称为对象)
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
使用闭包构建的对象的示例:
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