Javascript闭包语法

时间:2012-08-10 07:44:15

标签: javascript closures

这些结构之间有什么区别,优点/缺点(如果有的话)?

 new function(obj) {
     console.log(obj);
 }(extObj);

VS

 (function(obj) {
     console.log(obj);
 })(extObj);

3 个答案:

答案 0 :(得分:9)

第一个返回对新构造的匿名构造函数实例(= this)的引用。

第二个返回匿名函数的返回值。由于您的函数没有return语句,因此它将隐式返回undefined。

尝试以下方法:

var t1 = new function(obj) { console.log(obj); }(extObj);
var t2 =    (function(obj) { console.log(obj); })(extObj);

typeof t1 => "object"
typeof t2 => "undefined"

(顺便说一下,t1.constructor将返回您创建的t1原始函数。)

如果添加一个return语句,差异会变得更加清晰:

var t1 = new function(obj){ return(obj); }("foo");
var t2 =    (function(obj){ return(obj); })("bar");

console.log(t1) => "object"
console.log(t2) => "bar"

IMO,这使(function)()对于日常用例更有用 - 您将此函数执行的返回值分配给变量,如果您正在使用立即调用的函数,则该变量通常是您想要的。特别是当有更复杂的东西,如(伪代码)时:

var myNameSpace = (function(){
    /* do some private stuff here*/
    ...
    /* expose parts of your anonymous function by returning them */
    return{
       functionX,
       variable1,
       variable2
    }
}();

基本上,您可以使用任意一元运算符将函数声明转换为表达式,该表达式会立即被调用。所以你也可以写:

!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();

取决于函数的return语句,这些将给出不同的返回结果。 ! - 否定返回值+|-评估为数字(应用负号)~bitwise not应用于返回值。

答案 1 :(得分:4)

如果你正在寻找明确处理一个立即调用的函数,那么两者之间没有任何真正的区别,除了第一个将在函数内部返回this,外部世界,自动(即new所做的),默认情况下,如果未指定不同的返回值(常规函数返回undefined)。

剩下的主要差异实际上并不重要 - 访问原型链将毫无意义,返回this.constructor指向匿名函数会让您访问缓存匿名函数供以后使用(比如将它从事件监听器中删除,如果你以某种方式设法将所附函数粘贴在...... ......这本身就是一种技巧)。

允许人们将您的立即调用的函数缓存为返回的this对象的构造函数属性可能存在安全风险......或者它可能真的很有用...... ...非常具体的场景。

每天在线搜索代码的目的 - 没有真正的区别。

答案 2 :(得分:1)

另一个区别是第一次调用会创建一个额外的对象。在这里,我将名称fo表示为对象:

var o = new function f(obj) {
    console.log(obj);
}(extObj);

在第二种情况下,我们仍然创建一个函数对象f,但我们不创建o

(function f(obj) {
    console.log(obj);
})(extObj);

仍然会创建一个闭包,但是它比实际的JavaScript对象便宜,因为它不带有整个原型链或其他属性(如隐藏类引用),