Javascript之【闭包】

1. 变量做用域

要理解闭包,首先要先理解javascript变量的做用域 变量的做用域只有两种:全局变量 + 局部变量javascript

全局变量:任何地方均可以访问(函数内部、外部) 局部变量:只能在变量所在函数及函数的子函数中访问 :fa-exclamation-circle:注意:变量声明若是不使用var关键字,那么他就是一个全局变量,即便是在函数内部定义java

1.1 计算器困境

但愿计算器的值counter可以被修改,可是不但愿被任意更改(只能+1) 全局变量实现:闭包

var counter = 0;
    function add(){
        ++counter;
    }
		
    add(); //1
    add(); //2
    add(); //3
    问题:counter的值能够被任意更改。

局部变量实现:函数

function add(){
        var counter = 0;
        ++counter;
    }
		
    add(); //1
    add(); //1
    add(); //1
    问题:counter的值不能按照设想来正确输出。

javascript的闭包就能够解决该问题。性能

2. javascript内嵌函数

在javascript中,全部的函数都可以访问它们上层的做用域code

function add(){
    var counter = 0;
    function plus(){
        ++counter;
    }
}

上面代码中,plus函数在add函数内部,这使得add内部的全部局部变量都是对plus可见的,可是反过来却不行。 这就是javascript语言特有的【链式做用域】结构(chain scope)ip

若是咱们可以在外部访问plus函数,那么这个【计算机困境】就可以解决了 因此,只要将plus函数做为add函数的返回值,就能够访问plus函数了, 也就能够经过plus函数,在add函数外部访问add函数局部变量了内存

================ 以上所说就是闭包。ci

3. javascript中的闭包

当函数a的内部函数b被函数a外的一个变量引用的时候,就建立了一个闭包。 闭包就是将函数内部和函数外部链接起来的一座桥梁作用域

3.1 闭包的用途:
  1. 能够读取函数内部的变量
  2. 可让函数内部变量的值始终保存在内存中

计算机困境能够更改成如下两种方式:

1:(建议)
var add = (function(){
    var counter = 0;
    return function plus(){return ++counter;}
})();

add(); //1
add(); //2
add(); //3

2:
function add(){
    var counter = 0;
    return function plus(){return ++counter;}
    }
		
    var f1 = add(); 
    f1(); //1
    f1(); //2
    f1(); //3

以上证实:局部变量counter一直在内存中, 并无在函数执行完后自动清除。 why?????? because: --add是plus的父函数,而plus被赋给了一个全局变量,致使plus始终在内存中, 而plus函数依赖于add函数,因此add也一直在内存中,不会再结束后被GC回收。

3.2 getter/setter
function add(){
    var counter = 0;
    getCounter = function(){
        reutrn counter;
    }
}

注意add中的getCounter变量,由于没有使用var来声明,因此它是一个全局变量, 能够当作java中的getter来使用 :fa-hand-o-down:

public class add{
    private int counter = 0;
    public int getCounter(){
        return counter;
    }
}
3.3 闭包应该注意的问题
  1. 因为闭包使得函数中的变量,都被保存在内存中,内存消耗很大,因此不能滥用闭包。 不然会形成网页性能问题,甚至会内存泄漏。 解决方案:退出函数以前,将不使用的局部变量所有消除(变量的值为null便可)。
  2. 若是把函数当作Object使用,不要随便经过setter/闭包改变函数内部的变量值。
相关文章
相关标签/搜索