今天我们从内存结构上来解说下 javascript中的闭包概念。

闭包:是指有权訪问另外一个函数作用域中的变量的函数。

创建闭包的常见方式就是在一个函数内部创建另外一个函数。

在javascript中没有块级作用域。一般为了给某个函数申明一些仅仅有该函数才干使用的局部变量时,我们就会用到闭包,这样我们能够非常大程度上降低全局作用域中的变量。净化全局作用域。

使用闭包有如上的优点。当然这种优点是须要付出代价的,代价就是内存的占用。

怎样理解上面的那句话呢?

每一个函数的运行,都会创建一个与该函数相关的函数运行环境,或者说是函数运行上下文。这个运行上下文中有一个属性 scope chain(作用域链指针),这个指针指向一个作用域链结构,作用域链中的指针又都指向各个作用域对应的活动对象。

正常情况,一个函数在调用開始运行时创建这个函数运行上下文及对应的作用域链,在函数运行结束后释放函数运行上下文及对应作用域链所占的空间。

比方:

    //声明函数
function test(){
var str = "hello world";
console.log(str);
}
//调用函数
test();

在调用函数的时候会在内存中生成例如以下图的结构:

可是闭包的情况就有点特殊了。因为闭包函数能够訪问外层函数中的变量。所以外层函数在运行结束后,其作用域活动对象并不会被释放(注意。外层函数执 行结束后运行环境和相应的作用域链就会被销毁),而是被闭包函数的作用域链所引用,直到闭包函数被销毁后,外层函数的作用域活动对象才会被销毁。

这也正是 闭包要占用内存的原因。

所以使用闭包有优点。也有坏处,滥用闭包会造成内存的大量消耗。

使用闭包还有其它的副作用,能够说是bug。也能够说不是,相对不同的业务可能就会有不同的看法。

这个副作用是闭包函数仅仅能取到外层函数变量的终于值。

測试代码例如以下:(这里使用了jquery对象)

    /*闭包缺陷*/
(function($){
var result = new Array(),
i = 0;
for(;i<10;i++){
result[i] = function(){
return i;
};
}
$.RES1 = result;
})(jQuery);
// 运行数组中的函数
$.RES1[0]();

上面的代码先通过匿名函数表达式开辟了一块私有作用域,这个匿名函数就是我们上面所说的外层函数,该外层函数有一个參数$,同一时候还定义了变量result和 I , 通过for循环给数组result赋值一个匿名函数。这个匿名函数就是闭包,他訪问了外层函数的变量I , 理论上数组result[i]() 会返回对应的数组下标值,实际情况却不如所愿。

如上代码 $.RES1[0]() 的运行结果是10.

为什么会这样呢,由于i的终于值就是10.

以下我们通过下图来具体说明下,上面的那段代码运行时在内存中究竟发生了什么:

那么这个副作用有没有办法能够修复呢?当然能够。

我们能够通过以下的代码来达到我们的预期。

    /*修复闭包缺陷*/
(function($){
var result = new Array(),
i = 0;
for(;i<10;i++){
result[i] = function(num){
return function(){
return num;
}
}(i);
}
$.RES2 = result;
})(jQuery);
//调用闭包函数
console.log($.RES2[0]());

上面的代码又在内存中发生了什么?我们相同用以下的一幅图来详解。

看懂了上面的图,我们也就不难理解以下的图。

仅仅要看懂上面的三张图,我们也就能够深入的理解清楚javascript中闭包的原理。以及闭包的优点和弊端,在我们的代码中合理的使用闭包,达到代码的整洁和高效。

阅读原文:javascript闭包具体解释

javascript闭包具体解释的更多相关文章

  1. javascript 闭包 通俗解释

    代码段 function foo(){ var a = 2; function bar(){ console.log(a); } return bar; } var baz = foo(); baz( ...

  2. 最简明的JavaScript闭包解释

    最简明的JavaScript闭包解释 JavaScript是这几年最火的编程语言之一,从前端到服务器端,再到脚本,好像没有一个地方没有JavaScript的身影.这个世界上任何的一种事物的存在必然有其 ...

  3. 我从来不理解JavaScript闭包,直到有人这样向我解释它...

    摘要: 理解JS闭包. 原文:我从来不理解JavaScript闭包,直到有人这样向我解释它... 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 正如标题所述,JavaScript闭包 ...

  4. 我从来不理解 JavaScript 闭包,直到有人这样向我解释它...

    正如标题所述,JavaScript 闭包对我来说一直有点神秘,看过很多闭包的文章,在工作使用过闭包,有时甚至在项目中使用闭包,但我确实是这是在使用闭包的知识. 最近看国外的一些文章,终于,有人用于一种 ...

  5. javascript闭包—围观大神如何解释闭包

    闭包的概念已经出来很长时间了,网上资源一大把,本着拿来主意的方法来看看. 这一篇文章 学习Javascript闭包(Closure) 是大神阮一峰的博文,作者循序渐进,讲的很透彻.下面一一剖析. 1. ...

  6. 【javascript闭包】转载一篇不错的解释,也有几个大牛的链接

    初学闭包时一直以为很简单.但伴随对一个问题深入学习后,才算真正理解了闭包,同时也发现连<<JavaScript高级程序设计>>中都些不准确的地方. 我不准备从头介绍闭包的概念, ...

  7. 深入理解JavaScript——闭包

    跟很多新手一样我也是初入前端,对闭包的理解花费的时间和精力相当的多.效果也还行,今天我就来根据自己的理解细致的讲一讲闭包,由于是初入学习的时候不免有一些弯路和困惑,我想信这也是很多跟我一样的人会同样遇 ...

  8. JavaScript学习总结——我所理解的JavaScript闭包

    一.闭包(Closure) 1.1.什么是闭包? 理解闭包概念: a.闭包是指有权限访问另一个函数作用域的变量的函数,创建闭包的常见方式就是在一个函数内部创建另一个函数,也就是创建一个内部函数,创建一 ...

  9. JavaScript闭包(Closure)

    JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...

随机推荐

  1. SpringBoot 快速开发框架

    学习资源:https://ke.qq.com/course/260513(这是Springboot升级版本教程,里面还有一个初级版本的) 1.第一个测试程序,那个覆盖方法加上@Override会报错, ...

  2. 所有的工作目录 都要svn_开头,并且要进行svn同步,你能保证你不删除,你保证不了非你!

    所有的工作目录 都要svn_开头,并且要进行svn同步,你能保证你不删除,你保证不了非你! 血的代价啊~

  3. https://quotefancy.com/ 经典句子(英语) 真是特别好~

    https://quotefancy.com/ 经典句子(英语)

  4. CAD参数绘制样条线(com接口)

    在CAD设计时,需要绘制样条线,用户可以设置样条线线重及颜色等属性. 主要用到函数说明: _DMxDrawX::PathLineTo 把路径下一个点移到指定位置.详细说明如下: 参数 说明 DOUBL ...

  5. Matrix (二分套二分

    Given a N × N matrix A, whose element in the i-th row and j-th column Aij is an number that equals i ...

  6. BZOJ1079: [SCOI2008]着色方案 (记忆化搜索)

    题意:有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块. 所有油漆刚好足够涂满所有木块,即c1+c2+...+ck=n.相邻两个木块涂相同色显得很 ...

  7. python嵌套列表

    从excel读取一行信息添加到一个临时列表,最后将所有行的列表添加到一个大列表. 源码: import xlrd,reclass Info(): def read_info(self): data = ...

  8. pytorch笔记:09)Attention机制

    刚从图像处理的hole中攀爬出来,刚走一步竟掉到了另一个hole(fire in the hole*▽*) 1.RNN中的attentionpytorch官方教程:https://pytorch.or ...

  9. idea搭建SSM的maven项目(tomcat容器)

    一.创建maven的web项目 (1)选择项目的骨架 (2)写项目的坐标 (3)maven的设置 设置maven的本地仓库,以及配置文件的位置,同时点击+号,填入archetypeCatalog和in ...

  10. ehcache的学习笔记(一)

    学习ehcache文档: 介绍:Ehcache是一个开源的项目,用来提高性能的基于标准化的缓存,无需使用数据库,简化了可扩展性.他是最广泛使用的基于java的缓存,因为他是强壮的,被证实的,功能全面的 ...