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

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

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

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

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

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

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

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

比方:

  1. //声明函数
  2. function test(){
  3. var str = "hello world";
  4. console.log(str);
  5. }
  6. //调用函数
  7. test();

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

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

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

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

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

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

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

  1. /*闭包缺陷*/
  2. (function($){
  3. var result = new Array(),
  4. i = 0;
  5. for(;i<10;i++){
  6. result[i] = function(){
  7. return i;
  8. };
  9. }
  10. $.RES1 = result;
  11. })(jQuery);
  12. // 运行数组中的函数
  13. $.RES1[0]();

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

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

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

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

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

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

  1. /*修复闭包缺陷*/
  2. (function($){
  3. var result = new Array(),
  4. i = 0;
  5. for(;i<10;i++){
  6. result[i] = function(num){
  7. return function(){
  8. return num;
  9. }
  10. }(i);
  11. }
  12. $.RES2 = result;
  13. })(jQuery);
  14. //调用闭包函数
  15. 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. Linux——网络编程线程池机制

    #include <stdlib.h>#include <pthread.h>#include <unistd.h>#include <assert.h> ...

  2. 网络编程 - 协议遇到IO自动切换

    一.协议遇到IO自动切换 python网络编程,遇到IO自动切换,通过模块gevent来实现: import gevent,time def g1(): print ("g1 is star ...

  3. 1257 背包问题 V3(二分)

    1257 背包问题 V3 3 秒 131,072 KB 80 分 5 级题 题意 : 从n个物品中选出k个,使单位体积价值最大 思路: 一开始正面想,试过很多种,排序什么的..总是结果不对,最后想到二 ...

  4. Django, one-to-many, many-to-many

    1.定义关系 定义三个表,Publisher,Book,Author 一个作者有姓,有名及email地址. 出版商有名称,地址,所在城市.省,国家,网站. 书籍有书名和出版日期. 它有一个或多个作者( ...

  5. PHP编译参数configure配置详解(持续更新中)

    编译参数-使用 ./configure -h在源代码目录中,该命令可以查看所有编译参数以及对应的英文解释 编译参数-说明 --prefix=/opt/php //指定 php 安装目录--with-a ...

  6. 详细了解为什么支持Postman Chrome应用程序已被弃用?

    本地postman chrome插件确实也无法正常使用,只有Postman官方自己的软件应用程序可以使用.笔者多少追溯终于知道原因,并紧急上线了不同操作系统版本的Postman应用程序. 为什么近期P ...

  7. Python和Java的语法对比,语法简洁上python的确完美胜出

    Python是一种广泛使用的解释型.高级编程.通用型编程语言,由吉多·范罗苏姆创造,第一版发布于1991年.可以视之为一种改良(加入一些其他编程语言的优点,如面向对象)的LISP.Python的设计哲 ...

  8. 牛客网补题 New Game!(原Wannafly summer camp day2原题)

    思路:这个题在秦皇岛的时候好像没有写出来,反正我是没有写出来,题解是听懂了:把直线和圆都看做一个结点,圆和直线用点到直线的距离与半径差求出来,圆和圆之间用点和点之间的距离和半径差表示,最后最短路跑一遍 ...

  9. 我们参与投资36Kr股权众筹项目“易途8”的决策过程

     背景   中文接机.中文送机.中文包车. 当地玩乐   最大的竞争对手:皇包车,15年9月A轮   其它对手:唐人接等,订单量无法和 皇包车.易途8比.    看好理由 1.旅游行业和境外自由行,是 ...

  10. node学习的一些网站

    Node.js 包教不包会 篇幅比较少 node express 入门教程 nodejs定时任务 一个nodejs博客 [NodeJS 学习笔记04]新闻发布系统 过年7天乐,学nodejs 也快乐 ...