闭包,在一开始接触JavaScript的时候就听说过。首先明确一点,它理解起来确实不复杂,而且它也非常好用。那我们去理解闭包之前,要有什么基础呢?我个人认为最重要的便是作用域(lexical scope),如果对作用域和作用域链不理解的同学最好自己先去学一学,再回过头来,理解闭包,就更加轻松。

  下面便直接进入主题。

  我们知道一个函数是有作用域的,在函数内部定义的局部变量只有在函数内部才可以访问的到。一旦函数访问结束被销毁,局部变量随之也会销毁,无法通过任何方式再次访问局部变量,除了闭包。也就是说,我们可以通过闭包这一个方法,从函数的外部去访问到函数内部的变量,即使那个函数已经被销毁。没错,闭包最重要的用法就是,我们只提供某些接口去访问和修改局部变量,而外部是不能直接访问到局部变量的。

  说了那么多有关如何使用闭包,我们来看看闭包是长什么样子的。又到了举个栗子的环节,依然是最简单的people和name。

var people = function(){var name = "Yika";var sayName = function(){return name;  //访问了people函数的局部变量name
        }var setName = function(newName){name = newName;  //访问了people函数的局部变量name
        }return{sayName: sayName,setName: setName}//返回一个对象
    }var p1 = people();        //函数return的是一个对象,这个对象里有两个函数sayName和setNameconsole.log(p1.name);     //undefined.   name是people函数里的局部变量,而不是p1对象的属性,当然为undefinedconsole.log(p1.sayName());//"Yika"p1.setName("Ruyi");       //通过setName函数修改局部变量name的值console.log(p1.sayName());//"Ruyi"

  看完这个例子,想必对闭包多少有个了解啦,除了注释的内容,下面再做些补充。

  问:为什么局部变量name属性在people执行完之后,没有被销毁呢,反而数值还保存在内存中。

  答: 在例子中,函数注释那里专门写了(访问了people函数的局部变量name)。正是因为people函数里的sayName函数和setName函数访问了name属性,并且通过return传到了p1对象里,成了p1的两个方法。因为方法一直引用着people函数的局部变量,所以不会被消除,依然会在内存中。这样便形成了闭包,可以在函数外部访问到函数内部的局部变量。

  对此,我们可以换个更直观的写法。

var people = function(){var name = "Yika";var obj = {sayName: function(){return name;},setName: function(newName){name = newName}};return obj;       //直观的返回对象
    }
//下面的结果是一样的。

  当然闭包也不是一直那么好用,特别是在循环里。继续举例子

<body><input type="button"/><input type="button"/><input type="button"/><input type="button"/><input type="button"/><input type="button"/><input type="button"/><script type="text/javascript">var oBtn = document.getElementsByTagName('input');for(var i = 0, len = oBtn.length; i < len; i++){oBtn[i].onclick = function(){alert("value = " + i);    //闭包陷阱的发生地!永远输出 value = 7
            }}</script>
</body>

  当我们运行上面的代码的时候,我们是这样想的,循环一下按钮,并输出按钮所在的序号,但是我们得到的却永远是7。其实用我们之前讲的闭包会让变量的值一直保存在内存中的原理想一想,就应该懂了。当我们循环的时候按钮的点击事件时,是引用了for循环里的 i 变量。当所有按钮都绑定了点击事件后,i 的值也已经变成了7,当然所有的按钮输出的都是7啦!怎么解决这个问题也很好办的,但是我希望留下给大家思考。这里就说一下大致思路吧,我们可以在循环之外创建一个辅助函数,并让辅助函数return一个绑定当前 i 的函数。

  当然这里我也只是抛砖引玉的介绍了一下闭包,希望可以帮到大家浅显简单的了解闭包。

  还是那句话噢,有问题立即指正,我一定会立马检查更正,以免误导了大家!

转载于:https://www.cnblogs.com/YikaJ/p/4040631.html

JavaScript——以简单的方式理解闭包相关推荐

  1. 如何用最简单的方式理解傅立叶变换?

    你还在因为傅立叶挂科而头疼不已吗? 傅立叶变换经常被称为大学的杀手课程,傅立叶变换不仅仅是一个数学工具,更是一种可以彻底颠覆一个人以前世界观的思维模式. 但不幸的是,傅立叶变换的公式看起来太复杂了,所 ...

  2. JavaScript最简单的方式写万年历

    万年历 话不多说,直接进入主题,刚开始想写万年历的时候也想过要不要写一个复杂一点的出来,后来哦脑子容量有限就不自作自受了,毕竟bug太容易写出来了调试也确实烦的一批. 下面先看看预想的效果图吧· 我想 ...

  3. 图解DOM树(最简单的方式理解DOM树)

  4. 用最简单的方式来理解在单片机中的继电器的原理与接线

    一.电磁式继电器原理 1.电磁式继电器定义 单片机中用的比较多的是电磁式继电器,电磁式继电器一般由铁芯.线圈.衔铁.触点簧片等组成的.只要在线圈两端加上一定的电压,线圈中就会流过一定的电流,从而产生电 ...

  5. Map集合遍历的四种方式理解和简单使用

    Map集合遍历的四种方式理解和简单使用 ~Map集合是键值对形式存储值的,所以遍历Map集合无非就是获取键和值,根据实际需求,进行获取键和值 1:无非就是通过map.keySet()获取到值,然后根据 ...

  6. 我我我我终于理解闭包了,哈哈哈哈(仰天长啸)(JavaScript闭包理解)

    想要理解闭包.首先得了解JavaScript中的三个东西. 1,函数内部可以访问的范围. 就是说,函数内部能访问,自身内部以及自身外层的变量.(这个很好理解,大部分语言都是如此) 如: var a = ...

  7. [javascript] 看知乎学习js闭包

    知乎:到底什么是闭包? 寸志: JavaScript 闭包的本质源自两点,词法作用域和函数当作值传递. 词法作用域,就是,按照代码书写时的样子,内部函数可以访问函数外面的变量.引擎通过数据结构和算法表 ...

  8. javascript 近乎神话般的概念:闭包

    写在前面 JavaScript 一个近乎神话 对于JavaScript有使用经验但却从未真正理解闭包概念的人来说,理解闭包可以说是某种意义上的重生.闭包并不是需要学习新的语法才能使用的工具.闭包的产生 ...

  9. JavaScript 核心概念之作用域和闭包

    相信大家已经阅读了很多关于作用域和闭包文章,我也一样.作用域和闭包是 JavaScript 中的关键概念之一.当我阅读了<高性能的JavaScript>这本书后,我才完全理解这两个概念.所 ...

最新文章

  1. python string模块template_Template Strings
  2. java简单小程序_Java简易登录注册小程序
  3. 『飞鸽传书』WindowsPhone支持VS2010的开发工具出来了
  4. django 路由分发 url分层
  5. Laravel核心解读 -- Request
  6. Linux学习笔记003----linux yum命令详解
  7. qcustomplot 游标吸附_QCustomplot使用分享(九) 绘制图表-多功能游标
  8. k2 官方纯净版固件
  9. 通俗理解同步IO\异步IO
  10. 安卓代码设置系统时间
  11. 概率论与数理统计习题集及答案
  12. C++ 设计模式 简单工厂模式
  13. MATLAB自带插值函数
  14. ArcGIS技巧】下载偏移影像后纠偏操作
  15. win10系统更新后打开chrome浏览器几秒后自动闪退
  16. 如何管理好一个研发管理团队
  17. php 获取月份的周数,PHP获取当前月份的周数只能使用php
  18. 阿里企业邮箱smtp设置(实践)
  19. 各种抠图动态图片_抠图动画
  20. 如何用C#实现电子面单批量打印功能

热门文章

  1. Java(发布/订阅模式)
  2. javascript --- [有趣的条件]双等号的隐式调用和数据劫持
  3. 部署项目的问题(一)—— vue工程打包上线样式错乱问题
  4. 瓜子二手车发12月二手车价格:汉兰达奥德赛CR-V保值率居首
  5. 中本聪研究所创始人对Core的发展方向感到厌恶
  6. HTML入门学习 -- HTML基础知识
  7. Kohana和Zencart
  8. MemCache 分布式缓存
  9. 随心所欲的Web页面打印技术
  10. linux下c和c++互相调用