美文网首页我爱编程
闭包和立即执行函数

闭包和立即执行函数

作者: 隔壁老王z | 来源:发表于2018-06-10 00:32 被阅读0次
    • 闭包:先来看一个题目:实现一个函数,每次调用自增1

    你有可能会想用全局变量,计数的时候将它加一,但是全局变量有风险,你可能会不小心改掉它,或者有时候你不希望它能被改变。

    而局部变量只在函数内部有效,函数调用完后它就没了,而且全局无法使用。这时候闭包就登场了。

    function plus(){
            var a = 0;
            return function(){
                return ++a
            }
     }
     var pl = plus();
     console.log(pl()); //1
     console.log(pl()); //2
     console.log(pl()); //3
     var pl2 = plus();
     console.log(pl()); //1
    

    函数plus()定义了一个局部变量a,并返回了一个内部匿名函数,因为是内部函数,所以它可以访问其外部函数的局部变量a,并且将其加1并返回。但是由于“count()”函数已经调用完毕,我们将无法通过其他的任何办法修改"count()"中变量i的值,这就是闭包最实用的功能,就是将你想操作的变量或对象隐藏起来,只允许特定的方法才能访问。

    JS高程中对闭包的定义:闭包是指有权访问另一个函数作用域中的变量的函数

    • 立即执行函数

    函数表达式 后面 可以加() 立即调用该函数,函数声明不行 ,所以 我们想让函数声明 立即执行,就要想办法将函数声明 变成 函数表达式

    var fn = function(){
        console.log(1)
    }()//函数表达式后面加括号,正确
    function fn(){
      console.log(1)
    }()//会报错
    function fn(){
      console.log(1)
    }(1)//注意,不会报错,但这么写也没有意义,因为函数并不会立即执行
    function(){
      console.log(1)
    }()//报错,匿名函数未进行赋值操作
    
    var fn = function(a){
      console.log(a)
    }(1);//1
    (function(a){
      console.log(a)
    }(1));//1
    (function(a){
      console.log(a)
    })(1);//1
    !function(a){
      console.log(a)
    }(1);//1
    +function(a){
      console.log(a)
    }(1);//1
    -function(a){
      console.log(a)
    }(1);//1
    

    因此()、!、+、-、=运算符都可以将函数声明转换成函数表达式,然后后面加()立即执行函数的代码。

    立即执行函数通过定义一个匿名函数,创建了一个新的函数作用域,相当于创建了一个“私有”的命名空间,该命名空间的变量和方法,不会破坏污染全局的命名空间。此时若是想访问全局对象,将全局对象以参数形式传进去即可,如jQuery代码结构:

    (function(window,undefined){
        //jQuery code
    })(window);
    

    还有一个用途,就是让一个工厂方法只能被调用一次,也就是一个匿名函数,在声明的时候立即调用:

    var car = function(){
      var speed = 0;
      return {
        start:function(){
          speed = 60;
        },
        getspeed:function(){
          return speed
        }
      }
    }();
    car.start();
    console.log(car.getspeed());//60
    

    也可以写成:

    var car = (function(){
        ...
    })();
    或
    var car = (function(){
        ...
    }());
    

    car已经不是一个函数了,它是这个匿名的工厂方法执行完返回的对象。这两个函数所需要访问的“speed”变量对外不可见 ,同时你无法再次调用这个匿名的工厂方法来创建一个相同的对象 。

    相关文章

      网友评论

        本文标题:闭包和立即执行函数

        本文链接:https://www.haomeiwen.com/subject/ajoxeftx.html