JavaScript中闭包的概念、原理、做用及应用

微信图片_20200211175247.png

1、闭包概念

闭包:有权访问另外一个函数做用域中的变量的函数;通常状况就是在一个函数中包含另外一个函数。
从官方定义咱们知道闭包是一个函数,只不过这个函数有[超能力],能够访问到另外一个函数的做用域。
为何说这个叫作[超能力]呢?
由于咱们知道函数做用域是独立的、封闭的,外部的执行环境是访问不了的,可是闭包具备这个能力和权限。
那闭包是怎样的一个表现形式呢?
第一,闭包是一个函数,并且存在于另外一个函数当中
第二,闭包能够访问到父级函数的变量,且该变量不会销毁安全

function person(){
    var name = '有鱼';
    function cat(){
        console.log(name);
    }
    return cat;
}
var per = person();// per的值就是return后的结果,即cat函数
per();// 有鱼 per()就至关于cat()
per();// 有鱼 同上,并且变量name没有销毁,一直存在内存中,供函数cat调用
per();// 有鱼

闭包.jpg

2、闭包原理

闭包的实现原理,实际上是利用了做用域链的特性,咱们都知道做用域链就是在当前执行环境下访问某个变量时,若是不存在就一直向外层寻找,最终寻找到最外层也就是全局做用域,这样就造成了一个链条。
例如:微信

var age = 18;
function cat(){
    age++;
    console.log(age);// cat函数内输出age,该做用域没有,则向外层寻找,结果找到了,输出[19];
}
cat();//19

看到这里,你们都会说这不就是最简单的函数和变量形式吗?闭包在哪里?别急,咱们接着往下看:
若是咱们再次调用时,结果会一直增长,也就变量age的值一直递增。闭包

cat();//20
cat();//21
cat();//22

若是程序还有其余函数,也须要用到age的值,则会受到影响,并且全局变量还容易被人修改,比较不安全,这就是全局变量容易污染的缘由,因此咱们必须解决变量污染问题,那就是把变量封装到函数内,让它成为局部变量。函数

function person(){
    var age = 18;
    function cat(){
        age++;
        console.log(age);
    }
    return cat;
}
person();// 19
person();// 19

这里又出现问题了,每次调用函数person,进入该做用域,变量age就会从新赋值为18,因此cat的值一直是19;因此须要作一下调整:spa

var per = person();//per至关于函数cat
per();// 19 即cat() 这样每次调用不在通过age的初始值,这样就能够一直增长了
per();// 20
per();// 21

并且变量age在函数内部,不易修改和外泄,相对来讲比较安全。code

3、闭包做用

做用1:隐藏变量,避免全局污染
做用2:能够读取函数内部的变量
同时闭包使用不当,优势就变成了缺点:
缺点1:致使变量不会被垃圾回收机制回收,形成内存消耗
缺点2:不恰当的使用闭包可能会形成内存泄漏的问题
这里简单说一下,为何使用闭包时变量不会被垃圾回收机制收销毁呢,这里须要了解一下JS垃圾回收机制;
JS规定在一个函数做用域内,程序执行完之后变量就会被销毁,这样可节省内存;使用闭包时,按照做用域链的特色,闭包(函数)外面的变量不会被销毁,由于函数会一直被调用,因此一直存在,若是闭包使用过多会形成内存销毁。
timg (4).jpgblog

4、闭包应用

需求:实现变量a 自增
一、经过全局变量,能够实现,但会污染其余程序图片

var a = 10;
function Add(){
    a++;
    console.log(a);
}
Add();
Add();
Add();

二、定义一个局部变量,不污染全局,可是实现不了递增内存

var a = 10;
function Add2(){
    var a = 10;
    a++;
    console.log(a);
}
Add2();
Add2();
Add2();
console.log(a);

三、经过闭包,能够是函数内部局部变量递增,不会影响所有变量,完美!!作用域

var a  = 10;
function Add3(){
    var a = 10;
    return function(){
        a++;
        return a;
    };
};
var cc =  Add3();
console.log(cc());
console.log(cc());
console.log(cc());
console.log(a);
相关文章
相关标签/搜索