立即执行函数&表达式&,运算符&闭包初理解

120 阅读2分钟

立即执行函数:初始化时立即执行;执行完被销毁
立即执行函数必须得是一个表达式,才能被立即执行
常见表达式两种:①var a= ; ②形如(7>5)
闭包:能够读取其他函数内部变量的函数

1.立即执行函数

   (
     function (){
       //...
     }
   )();

1.1参入参数

   (
     function (a){
       console.log(a);
     }
   )(5);

细节:() 就是一个表达式,不管()里面是函数还是什么
var a = function (a){}; //这是一个表达式

1.1.2先理解表达式
  //定义一个表达式
  var a = 1;
  
  //()内部 5>3 是一个表达式
  if(5>3){
     console.log("5大于3")
  }

1.2立即执行函数的条件

只要是表达式,就可以通过 执行符号() 执行

1.2.2案例
   var a = function(){
       console.log("表达式1被执行")
   }();
   
   (
     function (){
       console.log("表达式2被执行");
     }
   )();
   
   //申明函数不是表达式  (注释下面代码再执行)
   function test(){
     console.log("编译失败,报语法错误");
   }();

image.png

1.2.3将申明函数转成表达式立即执行

补充 + - 运算符 都可以执行 +function(){}

   0||function test(){
     console.log("申明函数我也可以被立即执行");
   }();
1.2.4 ,运算符

console.log((5,6));//输出最后一个,的右边的值

image.png

1.3验证执行后销毁

   var test1 = function (){
       console.log("立即执行");
   }();
   
   //undefined
   console.log(test1);

image.png

1.4经典案例

本想打印0到9,结果打印的全是10

   function test(){
       var arr = [];
       for(var i=0;i<10;i++){
          arr[i] = function(){
             document.write(i+"\t");
          }
       }
       return arr;
   }
   var myArr = test();
   myArr.forEach(function(item,key){
      item();
   });

image.png

为什么执行结果是这样???

var i=0; for(;i<10){
arr[i] = function(){document.write(i+"\t")}
i++;
}
//i从0到10执行完,返回arr数组,但是arr数组的每个元素是一个匿名函数指向了这个test的AO作用域,就不能销毁test()的AO作用域。这既是闭包!!!

1.4.2闭包
  function test(){
        var a=100;
        function add(){
            a++;
            console.log(a);
        }
        function sub(){
           a--;
           console.log(a);
        }
        return [add,sub];
    }
    //正常test()执行完,是要被销毁的,但是由于add,sub方法被返回,那么 test()的作用域链回归定义时,
    //内部方法依然是定义(上级执行)时的作用域链
    //test()此时的作用域链:只有一个GO    addsub的作用域链:GOtest()的AO
    var arr = test();//这里的test()代表的是test()的返回值,add和sub方法
    arr[0];//101
    arr[1];//100
1.4.3通过立即执行函数解决案例问题
  function test(){
       var arr = [];
       for(var i=0;i<10;i++){
          (
            //立即执行,这样每次就可以把外界的i的值拿到,传入形参
            function (innerI){
              arr[innerI]=function(){
                  document.write(innerI+"\t");
               }
            }
          )(i);
       }
       return arr;
   }
   var myArr = test();
   myArr.forEach(function(item,key){
      item();
   });