javascript闭包具体解释

今天我们从内存结构上来解说下 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闭包具体解释的更多相关文章
- javascript 闭包 通俗解释
代码段 function foo(){ var a = 2; function bar(){ console.log(a); } return bar; } var baz = foo(); baz( ...
- 最简明的JavaScript闭包解释
最简明的JavaScript闭包解释 JavaScript是这几年最火的编程语言之一,从前端到服务器端,再到脚本,好像没有一个地方没有JavaScript的身影.这个世界上任何的一种事物的存在必然有其 ...
- 我从来不理解JavaScript闭包,直到有人这样向我解释它...
摘要: 理解JS闭包. 原文:我从来不理解JavaScript闭包,直到有人这样向我解释它... 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 正如标题所述,JavaScript闭包 ...
- 我从来不理解 JavaScript 闭包,直到有人这样向我解释它...
正如标题所述,JavaScript 闭包对我来说一直有点神秘,看过很多闭包的文章,在工作使用过闭包,有时甚至在项目中使用闭包,但我确实是这是在使用闭包的知识. 最近看国外的一些文章,终于,有人用于一种 ...
- javascript闭包—围观大神如何解释闭包
闭包的概念已经出来很长时间了,网上资源一大把,本着拿来主意的方法来看看. 这一篇文章 学习Javascript闭包(Closure) 是大神阮一峰的博文,作者循序渐进,讲的很透彻.下面一一剖析. 1. ...
- 【javascript闭包】转载一篇不错的解释,也有几个大牛的链接
初学闭包时一直以为很简单.但伴随对一个问题深入学习后,才算真正理解了闭包,同时也发现连<<JavaScript高级程序设计>>中都些不准确的地方. 我不准备从头介绍闭包的概念, ...
- 深入理解JavaScript——闭包
跟很多新手一样我也是初入前端,对闭包的理解花费的时间和精力相当的多.效果也还行,今天我就来根据自己的理解细致的讲一讲闭包,由于是初入学习的时候不免有一些弯路和困惑,我想信这也是很多跟我一样的人会同样遇 ...
- JavaScript学习总结——我所理解的JavaScript闭包
一.闭包(Closure) 1.1.什么是闭包? 理解闭包概念: a.闭包是指有权限访问另一个函数作用域的变量的函数,创建闭包的常见方式就是在一个函数内部创建另一个函数,也就是创建一个内部函数,创建一 ...
- JavaScript闭包(Closure)
JavaScript闭包(Closure) 本文收集了多本书里对JavaScript闭包(Closure)的解释,或许会对理解闭包有一定帮助. <你不知道的JavsScript> Java ...
随机推荐
- Jmeter中的参数化常用的几种方式
Jmeter中的参数化常用的几种方式,这里讲一下前两个方式,最后一个在csv参数化里已详细讲解. 1.用户参数 2.函数助手 3.CSV Data Set Config 一.用户参数 位置:添加-前 ...
- CAD参数绘制角度标注(网页版)
主要用到函数说明: _DMxDrawX::DrawDimAngular 绘制一个角度标注.详细说明如下: 参数 说明 DOUBLE dAngleVertexX 角度标注的顶点的X值 DOUBLE dA ...
- 第3节 mapreduce高级:8、9、自定义分区实现分组求取top1
自定义GroupingComparator求取topN GroupingComparator是mapreduce当中reduce端的一个功能组件,主要的作用是决定哪些数据作为一组,调用一次reduce ...
- CGPathAddArc
使用CGPathAddArc使UIView的Layer绕中心点旋转 2012-12-04 15:38 775人阅读 评论(0) 收藏 举报 animationAnimationiosiOSIOSlay ...
- extjs中Store和grid的刷新问题
问题1:Store.load() 和Store.setproxy()区别 问题2:修改后的Grid 更新: Store.reload() 问题3,store删除后刷新会出问题 Store移除一行:St ...
- NOIP专题复习2 图论-生成树
目录 一.知识概述 二.典型例题 1.口袋的天空 三.算法分析 (一)Prim算法 (二)Kruskal 四.算法应用 1.[NOIP2013]货车运输 五.算法拓展 1977: [BeiJing20 ...
- node new Buffer()详解
new Buffer(size) size {Number} 分配一个 size 字节大小的新 Buffer.size 必须小于等于 require('buffer').kMaxLength(在64位 ...
- 字符串str.format()方法的个人整理
引言: 字符串的内置方法大致有40来个,但是一些常用的其实就那么20几个,而且里面还有类似的用法,区分度高比如isalpha,isalnum,isdigit,还有一些无时不刻都会用到的split切分, ...
- 51NOD 2370 奈芙莲的护符
>>这是原题传送门<< 答案参考来自 http://www.cnblogs.com/sugewud/p/9822933.html 思路:看到取值范围之后,仅有的思路还是暴力
- 11-看图理解数据结构与算法系列(B树的删除)
删除操作 删除操作比较复杂,主要是因为删除的项可能在叶子节点上也可能在非叶子节点上,而且删除后可能导致不符合B树的规定,这里暂且称之为导致B树不平衡,于是要进行一些合并.左旋.右旋等操作,使之符合B树 ...