Js中闭包的概念、原理、作用及应用

更新日期: 2020-01-16阅读: 1.7k标签: 闭包

一、闭包概念
闭包:有权访问另一个函数作用域中的变量的函数,一般情况就是在一个函数中包含另一个函数。
从官方定义我们知道闭包是一个函数,只不过这个函数有[超能力],可以访问到另一个函数的作用域。
为什么说这个叫做[超能力]呢?
因为我们知道函数作用域是独立的、封闭的,外部的执行环境是访问不了的,但是闭包具有这个能力和权限。
那闭包是怎样的一个表现形式呢?
第一,闭包是一个函数,而且存在于另一个函数当中
第二,闭包可以访问到父级函数的变量,且该变量不会销毁

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


二、闭包原理
闭包的实现原理,其实是利用了作用域链的特性,我们都知道作用域链就是在当前执行环境下访问某个变量时,如果不存在就一直向外层寻找,最终寻找到最外层也就是全局作用域,这样就形成了一个链条。
例如:

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;所以需要做一下调整:

var per = person();//per相当于函数cat
per();// 19 即cat() 这样每次调用不在经过age的初始值,这样就可以一直增加了
per();// 20
per();// 21

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



三、闭包作用
作用1:隐藏变量,避免全局污染
作用2:可以读取函数内部的变量
同时闭包使用不当,优点就变成了缺点:
缺点1:导致变量不会被垃圾回收机制回收,造成内存消耗
缺点2:不恰当的使用闭包可能会造成内存泄漏的问题
这里简单说一下,为什么使用闭包时变量不会被垃圾回收机制收销毁呢,这里需要了解一下JS垃圾回收机制;
JS规定在一个函数作用域内,程序执行完以后变量就会被销毁,这样可节省内存;使用闭包时,按照作用域链的特点,闭包(函数)外面的变量不会被销毁,因为函数会一直被调用,所以一直存在,如果闭包使用过多会造成内存销毁。


四、闭包应用
需求:实现变量a 自增
1、通过全局变量,可以实现,但会污染其他程序

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

 2、定义一个局部变量,不污染全局,但是实现不了递增

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

3、通过闭包,可以是函数内部局部变量递增,不会影响全部变量,完美!!

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);

 

链接: https://fly63.com/article/detial/7444

前端开发闭包理解,JavaScript-闭包

闭包(closure)是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠...

使用闭包的方式实现一个累加函数 addNum

使用闭包的方式实现一个累加函数 addNum,参数为 number 类型,每次返回的结果 = 上一次计算的值 + 传入的值

javascript中闭包最简单的介绍

JavaScript 变量可以是局部变量或全局变量。私有变量可以用到闭包。闭包就是将函数内部和函数外部连接起来的一座桥梁。函数的闭包使用场景:比如我们想要一个函数来执行计数功能。

js循环中的异步&&循环中的闭包

for循环中let 和var的区别,setTimeout(func,time)函数运行机制,一个需求,一个数组array[1,2,3,4,5],循环打印,间隔1秒

深入了解JavaScript的闭包机制

这篇文章主要介绍了JavaScript的闭包机制,针对内嵌函数的变量访问等问题分析了JS的闭包,写的十分的全面细致,具有一定的参考价值,JavaScript 变量可以是局部变量或全局变量。 私有变量可以用到闭包。

JavaScript 作用域、命名空间及闭包

变量作用域:一个变量的作用域是程序源代码中定义这个变量的区域,在函数内声明的变量是局部变量,它只在该函数及其嵌套作用域里可见(js 函数可嵌套定义);

Js中的闭包

闭包是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式就是在一个函数内部创建另一个函数。来看下面的示例:

js闭包问题

使用闭包能够让局部变量模拟全局变量一样,但是它只能被特定函数使用。我们都知道:1.全局变量可能会造成命名冲突,使用闭包不用担心这个问题,因为它是私有化,加强了封装性,这样保护变量的安全

JS之闭包的定义及作用

在学习闭包之前,你必须清楚知道JS中变量的作用域。JS中变量的作用域无非就全局变量和局部变量,两者之间的关系是函数内部可以直接访问全局变量,但是函数外部是无法读取函数内部的局部变量的

Js函数高级-闭包

JavaScript的运行机制:(1)所有同步任务都在主线程上执行,形成一个执行栈。(2)主线程之外,还有一个“任务队列”,只要异步任务有了运行结果,就在“任务队列”之中放置一个事件。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!