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 ...
随机推荐
- Hibernate修改操作 删除操作 查询操作 增加操作 增删改查 Hibernate增删查改语句
我用的数据库是MySQL,实体类叫User public class User { private Integer uid; private String username; private Stri ...
- 第1节 MapReduce入门:mapreduce的wordcount程序执行问题
执行时报错: 19/06/03 23:00:41 INFO Configuration.deprecation: session.id is deprecated. Instead, use dfs. ...
- C++ typedef用法小结 (转载)
声明:本文转自charley_yang,点击此处查看原文 第一.四个用途 用途一: 定义一种类型的别名,而不只是简单的宏替换.可以用作同时声明指针型的多个对象.比如:char* pa, pb; // ...
- IDEA下Eclipse快捷键
- MyBatis 实现分页功能
MySQL 的分页功能是基于内存的分页(即查出来所有记录,再按起始位置和页面容量取出结果). 案例:①根据用户名(支持模糊查询).用户角色 id 查询用户列表(即根据用户名称或根据用户角色 id 又或 ...
- POJ 2718 Smallest Difference(贪心 or next_permutation暴力枚举)
Smallest Difference Description Given a number of distinct decimal digits, you can form one integer ...
- POJ1222熄灯问题【位运算+枚举】
EXTENDED LIGHTS OUT Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14231 Accepted: 8 ...
- 将Java程序打包成可执行EXE文件的步骤
需要的工具myeclipse .jar2exe(附上下载地址,直接解压就可以用链接: https://pan.baidu.com/s/1qYPRgXu 密码: wbva) 1.将Java项目导出成.j ...
- 洛谷 通天系列 P1760 P1757 P1759
P1760 通天之汉诺塔 汉诺塔问题.一个高精乘单精解决 ans=2^n-1 /*by SilverN*/ #include<algorithm> #include<iostream ...
- [NOIP2006] 普及组
明明的随机数 STL真是偷懒神器 /*by SilverN*/ #include<algorithm> #include<iostream> #include<cstri ...