• JS闭包实例介绍


    JS作用域链讲起来麻烦,本来很好懂的东西,书上讲的很混乱。

    先撇开作用域的概念。采用自顶向下的方法来说明,可能会好点。
     
    好,其实全局变量和局部变量大家都懂得。全局变量很容易理解,就是一个内存共享原理。
    局部变量是是只属于它的父级(其实就是作用域),也就是说我们必须要找到父级才能找到它。
     
    有没有办法让我们从外部访问局部变量,而不用每次去找它的父级。
    比如:
    var a = 'out';
    var f = function(){
        var i = 'in';    //var表示声明 i 为局部变量,并定义它的指
    }    //返回给f的是并不执行的函数
    f();    //执行函数,创建局部变量i
    //a = i; 这是行不通的,因为 i 是局部变量,外部不可访问
     
     
    我们知道function() 这个(匿名)函数,一旦执行完,里面的变量或资源我们将不能再获取和使用,除非有办法让里面的资源驻留在我们能够找到存放地的内中。然后我们会想到静态变量,不过JS是没有静态变量的,那我们还是只有用全局变量的方法了么?是,也不是。是,因为我们还可以用闭包,不是,因为闭包也是一种间接的全局变量,不过这种手段让局部变量也有可全局分享的作用。这里的实例用个形象比喻就是,我们用一个绳子(作用域链)栓住了那个局部变量。
     
    var a='out';
    var a_find_in;    //声明一个绳子
    var f = function(){
        var i = 'in';
        a_find_in = function(){    //拴住 i 这个变量
            return i;    //返回这个i的值
        };
    }
    f();    //执行函数,创建局部变量 i
    a = a_find_in();    //获取局部变量 i 的值
     
     
    看到 a_find_in 这个函数相当于一个传递局部变量值的作用,它和 i 绑定在一起就像一个全局变量。只不过a_find_in充当这”全局变量“的地址,i 就是这个”全局变量“的值。有人会说,非得搞一个 a_find_in 出来,不如直接把 i 设置为全局不更简单么。
    闭包的作用不单单是为了使用局部变量。你可以看到这里 a_find_in 的作用只是返回给我们 i 的值,我们却不能像全局变量一样修改它。说到这,知道私有变量的话,就明白闭包这个可以让变量隐藏变的安全的作用了。
    其次,我们还可以声明和定义一个可以修改局部变量的函数。不过在这之前,还有一个闭包需要特别注意的点要说。
     
    若以上代码,我加上一行如下红色代码:
    var a='out';
    var a_find_in;    //声明一个绳子
    var f = function(){
        var i = 'in';
        a_find_in = function(){    //拴住 i 这个变量
            return i;    //返回这个i的值
        };
        i = 'change in';    //让 i 在这个作用域里面改变了值
    }
    f();    //执行函数,创建局部变量 i
    a = a_find_in();    //获取局部变量 i 的值
     
    以上代码 a 会得到 ’change in‘ 的值。这就是闭包的作用。为什么呢,先不解释,再看下面的代码。
     
    var a='out';
    var a_find_in;    //声明一个绳子
    var f = function(){
        var i = 'in';
        a_find_in = function(){    //拴住 i 这个变量
            return i;    //返回这个i的值
        }();    //立即执行
        i = 'change in';    //让 i 在这个作用域里面改变了值
    }
    f();    //执行函数,创建局部变量 i
    a = a_find_in;    //获取局部变量 i 的值
     
    以上代码 a 会得到 'in' 的值,因为函数立即执行,立即返回,a_find_in 在定义的时候加上了 '()',就相当于绳子一栓到当前的 i 值就立刻收绳,从而也不再和 i 指绑定,失去了闭包关系。就相当于 a_find_in = i; 取了当前 i 的值。
     
    对以上得到 'change in' 的闭包代码,如要从作用域链的角度去理解,i 就是关键点。function(){return i;} 这个函数赋给了 a_find_in,其实就是把 i 的作用域又链到了 function(){} 这个匿名函数的作用域中,但是 function(){} 现在赋给了外部变量 a_find_in 就相当于有了名字,我们随时可以呼唤(执行)这个函数,从而使用它的作用域,也就可以得到 i 甚至操作 i 的值了。
  • 相关阅读:
    开源:不断创新的动力
    Inkpad中文翻译已合并到官方项目
    Inkpad绘图原理浅析
    Vectoroid
    发布大幅重构优化的 TouchVG 1.0.2
    清理掉一直想研究的开源项目
    函数指针调用方式
    音视频直播优化
    std::unique_lock与std::lock_guard区别示例
    c++容器的操作方法总结
  • 原文地址:https://www.cnblogs.com/iwish/p/4434965.html
Copyright © 2020-2023  润新知