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 ...
随机推荐
- Swift 性能相关
起初的疑问源自于「在 Swift 中的, Struct:Protocol 比 抽象类 好在哪里?」.但是找来找去都是 Swift 性能相关的东西.整理了点笔记,供大家可以参考一下. 一些疑问 在正题开 ...
- CAD使用SetxDataString写数据(com接口)
主要用到函数说明: MxDrawEntity::SetxDataString 写一个字符串扩展数据,详细说明如下: 参数 说明 [in] BSTR val 字符串值 szAppName 扩展数据名称 ...
- oracle调用存储过程和函数返回结果集
在程序开发中,常用到返回结果集的存储过程,这个在mysql和sql server 里比较好处理,直接返回查询结果就可以了,但在oracle里面 要 out 出去,就多了一个步骤,对于不熟悉的兄弟们还得 ...
- 笔试算法题(11):Josephus环 & Fibonacci序列
出题:Josephus Cycle,约瑟夫环问题.k个数字连成一个环,第一个数字为1.首先从1开始计数删除第m个数字:然后从上次被删除的数字的下一个数字开始计数,删除第m个数字:重复进行第二步直到只剩 ...
- myBatis查询报错 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near
myBatis查询报错 You have an error in your SQL syntax; check the manual that corresponds to your MySQL se ...
- KBE实践——登录案例
目录 服务器 ``` void maini(){ printf("hello world"); } ``` 最小资产库创建 entity配置 实体的Python实现 创建第一个空间 ...
- dubbo理解
Dubbo服务的调用基本上都是出现在分布式项目中,最常见的电商网站.涉及买卖的APP等. 比如某个购物APP,目前最常见的架构就是做成分布式架构,拆分成很多个系统,比如用户模块.短信模块.产品模块.订 ...
- [Python3网络爬虫开发实战] 1.3.3-pyquery的安装
pyquery同样是一个强大的网页解析工具,它提供了和jQuery类似的语法来解析HTML文档,支持CSS选择器,使用非常方便.本节中,我们就来了解一下它的安装方式. 1. 相关链接 GitHub:h ...
- 用LAMP构架创建DISCUZ论坛
# rpm -q httpd mariadb mariadb-server php php-mysql # yum -y install httpd mariadb-server php php-my ...
- CSU1160
十进制-十六进制 Time Limit: 1 Sec Memory Limit: 128 MB Description 把十进制整数转换为十六进制,格式为0x开头,10~15由大写字母A~F表示. ...