首页 > 代码库 > ()()表达式立即执行的记录

()()表达式立即执行的记录

了解过js的同学基本上都遇到过()()这种方式的函数体。一开始我也不懂这是啥,没见过啊,这特么到底是什么玩意?具体深入了解后,才知道这是匿名函数直接执行的一种写法。看过某些帖子上有一个经典的例子,在此记录下来。

这种方式叫函数的闭包(closure),可以让匿名函数立即被执行(最后面的那对括号就是让上面定义的匿名函数立即执行的秘密),这种闭包有以下几个优势或特点:
1. 减少了全局变量的个数,可以有效减少命名冲突
   原因是包在里面的变量对于外面来说是不可见的,他们的作用域近局限在匿名函数的函数体内
2. 这种方式可以保存闭包外面的变量的状态,这个特点还是举个例子比较易懂:

function fn() {
    for(var i=0 ; i<2; i++) {
    //(function(){
        var backup = i;
        setTimeout(function() {
            alert(backup);
        }, 2000);
    //})();
    }
}
 
fn();

  上面代码的for循环一共两次,我们本来的目的是每隔两秒钟把每一次循环的索引(也就是i)输出,我们期待它应该输出:0和1,但是实际输出结果却是两次都是1
使用了闭包之后,我们会把循环中每一次i值的状态都保存下来,如下代码所示:

function fn() {
    for(var i=0 ; i<2; i++) {
    (function(){
        var backup = i;
        setTimeout(function() {
            alert(backup);
        }, 2000);
    })();
    }
}
 
fn();

  这次我们得到了正确的结果:0和1。因为闭包引用的是父函数范围内的最终值。

括号表达式,写起来精简,另外匿名函数就执行了,不过这么写函数就没办法通用了。

最后再来看看下面这种写法,传参的一种形式。

function f() {   
  var a = [];   
  var i;   
  for(i = 0; i < 3; i++) {   
    a[i] = (function(i){   
      return function(){   
        alert(i);   
        return i;   
      }   
    })();   
  }   
  return a;   
}   
  
var a = f();   
a[0]();//undefined  
a[1]();//undefined  
a[2]();//undefined  
---------------------------
function f() {   
  var a = [];   
  var i;   
  for(i = 0; i < 3; i++) {   
    a[i] = (function(x){   
      return function(){   
        alert(x);   
        return x;   
      }   
    })(i);   
  }   
  return a;   
}   
  
var a = f();   
a[0]();//0 
a[1]();//1
a[2]();//2

  上面的代码可以得出一个结论。js中,表达式立即执行()()的这种写法可以表示为(匿名表达式)(需要传入的参数),即(function(arg1,arg2,...){})(arg1,arg2,...),能表达这种写法的最简便的代码如下:

(function(a,b,c){
    alert(a);
    alert(b);
    alert(c);
})(1,2,3);

//打印结果
//1
//2
//3

  

()()表达式立即执行的记录