美文网首页javaScript
JavaScript--闭包(Closure)

JavaScript--闭包(Closure)

作者: 反者道之动001 | 来源:发表于2017-07-05 18:30 被阅读135次

    闭包(Closure)是一个老生常谈的话题,也是JavaScript重要的特性之一(闭包和异步)

    说闭包之前我们先了解下作用域(scopes)

    作用域分为全局变量和局部变量。
    在函数下定义var就会产生一个局部变量,否则就会创建一个全局变量。全局变量是一个定时炸弹,要小心对待。
    可以开启严格模式检查 'use strict'

    JavaScript有一个特性,外部的访问不到内部的,内部可以访问外部的。
    var a = 0
    ;(function cope(){
        var b = 1
        console.log(a)// 0
    })()
    console.log(b)// defined
    

    另一个作用域想要获取内部作用域变量,需要变通下。

    var a = 0
    ;(function cope(){
        var b = 1
        console.log(a)//0
        ;(function test(){
            console.log(b)// 1
        })()
    })()
    

    上面的代码里,test嵌套在cope里面,test可以访问cope里面的变量,那么就是闭包么,也许是吧,但确切说并不是。
    为什么说是,因为test嵌套在cope函数里面,test可以访问到cope的代码。
    为什么说不是,因为这只是满足了一部分闭包的一部分规则,但这是最重要的。

    那什么是闭包
    var c = (function(){
        var _var = 0
        function test(){
            console.log(_var)
        }
        return test
    })()
    c()// 妈妈,你看这就是闭包
    

    对比上面的代码,有什么变化? 对,就是return回去,然后实际调用。
    test函数在外部调用,闭包可以继续享受定义时的语法作用域。

    注意:闭包创建完之后,this是window

    闭包可以有效防止变量冲突,还有一个常用的是立即执行函数(IIFE)
    如上面的代码

    // 显示函数请用(function(){})() 的写法,不然外部调用不到
    ;!function(){
        // lalalalalala
    }()
    

    我们利用IIFE来解决不希望copes发生的事情。

    var arr = []
    for(var i=0; i < 10; i++){
      arr[i] = function(){
        console.log(i)
      }
    }
    arr[0]() //  10 纳尼?妈妈,这是怎么回事?
    

    妈妈:因为所有函数共享同一个[[Scope]]
    试着用IIFE得到真确的值:

    var arr = []
    for(var i=0; i < 10; i++){
      ;(function(i){
        arr[i] = function(){
         console.log(i)
        }
      })(i)
    }
    arr[0]()
    

    严格来说IIFE并不是闭包。

    写一个柯里化玩玩
    function a(){
      var i = 0
      function init(v){
        i = v+i
        console.log(i)
        return init
      }
      return init
    }
    var a = a()
    

    更多实例请看开源的库,比如书生写的XXY

    如遇到错误,恳请批评指正,谢谢!

    ---END--

    相关文章

      网友评论

      本文标题:JavaScript--闭包(Closure)

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