闭包的概念

  • 闭包是指有权访问另一个函数作用域中的变量的函数
  • 闭包是基于词法作用域书写代码时所产生的必然结果。
  • 函数对象可以通过作用域关联起来,函数体内的变量都可以保存在函数作用域内,这在计算机科学文献中称为“闭包”,所有的javascirpt函数都是闭包
  • 函数可以通过作用域链相互关联起来,函数内部的变量可以保存在其他函数作用域内,这种特性在计算机科学文献中称为闭包。
  • 闭包不是一个函数,它是一种机制,用于访问自由变量

优点

  • 不会造成全局变量的污染;
  • 可以在函数的外部访问到函数内部的局部变量(实现所谓的变量‘公有化’)。
  • 让这些变量始终保存在内存中,不会随着函数的结束而自动销毁。

缺点

  • 闭包导致作用域链的不释放,会造成内存溢出,所以就会占用内存空间, IE容易造成内存泄露

解决方法——使用完变量后,手动将它赋值为null

  • 闭包可能在父函数外部,改变父函数内部变量的值。
  • 由于闭包涉及跨作用域的访问,所以会导致性能损失。

解决方法——通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响

代码片段一:

 <p>1</p><p>2</p><p>3</p>var ps = document.querySelectorAll('p');for (var i = 0; i < ps.length; i++) {ps[i].onclick = function () {console.log(i);}}console.log(i); //3

这是因为for循环已经加载完毕,可以看到每个p标签都有点击事件,而onclick是点击之后才执行的,属于同步和异步问题。当我们点击的时候,for循环已经完成,所以i的值恒为3。产生这样的问题在于这个i的值在初始化完成的时候就已经是3了

原因

  • 函数作用域 function{ },块级作用域 {}。
  • 一定要有 function 关键字,才会有函数作用域。
  • js里面 var声明的变量只有函数作用域,没有块级作用域。(也就是说,函数可以隔离变量,for不能隔离变量)。
  • 因此,可在全局(外部)通过console.log看到 i 的值。

解决方案

1.let/const 块级作用域(推荐)

    var ps = document.querySelectorAll('p');for (let i = 0; i < ps.length; i++) {ps[i].onclick = function () {console.log(i);}}console.log(i);

 2.闭包:用立即执行的匿名函数把它包装起来,这样子做的话,log(i)的值就取自闭包环境中的i

    for (var i = 0; i < ps.length; i++) {(function (i) {ps[i].onclick = function () {console.log(i);}})(i);}

3.添加自定义属性 

  for (var i = 0; i < ps.length; i++) {//自定义属性标签ps[i].index = i;ps[i].onclick = function () {console.log(this.index);}}

js闭包深入理解(Closure)相关推荐

  1. JS闭包的理解及常见应用场景

    JS闭包的理解及常见应用场景 一.总结 一句话总结: 闭包是指有权访问另一个函数作用域中的变量的函数 1.如何从外部读取函数内部的变量,为什么? 闭包:f2可以读取f1中的变量,只要把f2作为返回值, ...

  2. 面试官:谈谈对JS闭包的理解及常见应用场景(闭包的作用)

    文章目录 对JS闭包的理解及常见应用场景(闭包的作用) 1.变量作用域 2.如何从外部读取函数内部的变量? 3.闭包概念 4.闭包用途 5.闭包的理解 6.闭包应用场景 setTimeout传参 回调 ...

  3. 浅谈对js闭包的理解

    闭包就是能够读取其他函数内部变量的函数.由于在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成"定义在一个函数内部的函数".在本质上,闭包是将函数内 ...

  4. 谈一谈对JS闭包的理解

    个人觉得理解闭包,首先要理解以下几个概念. 1.函数的作用域和作用域链 js不像java等其他类语言,它并不存在块级作用域,取而代之的是函数作用域,另一个变量作用域是全局作用域. 函数的作用域:变量在 ...

  5. js闭包的理解和作用

    一.为什么引入闭包 JS为每个变量对象定了作用域,在ES5 中只有全局作用域和函数作用域,没有块级作用域,由内向外形成作用域链,函数外部不能访问函数内部作用域的局部变量.在实际开发中会带来很多不便. ...

  6. js闭包是什么?对js闭包的理解

    结合 MDN 官网中 JavaScript 章节中对闭包详解,我们需要理清的问题有,什么是闭包.闭包产生的条件.以及闭包的用途. 1.1 闭包的概念 闭包(closure)是一个函数以及其捆绑的周边环 ...

  7. js闭包的理解以及闭包中this的理解

    javascript 闭包.this 2016-01-25  js pl 闭包其实很好理解,但是由于经常把this和闭包绑在一起,从而加大了理解的难度,如果将他们分开考虑,那就清晰多了. 闭包 闭包并 ...

  8. js闭包的理解及应用场景

    函数的声明与执行 函数定义阶段 1.会在堆内存中开辟一个存储空间 把函数体放在这个空间里 函数中的所有变量不解析 2.把这个空间地址赋值给函数名 然后储存在栈内存中 函数调用阶段 1.根据函数名找到对 ...

  9. JS / 闭包的理解

    闭包实际上就是一个函数,只不过这个函数有些特殊,它定义在另一个函数内部,通过它可以在 js 中模仿出访问 C++ 中的私有成员变量的效果. 代码如下: function Test() {var cou ...

最新文章

  1. 【带你重拾Redis】Redis事务
  2. Linux 基金会透露未来 Linux 内核可能会引入形式验证
  3. ORACLE 字符串超长问题解决方案
  4. 使用OpenVAS 9进行漏洞扫描
  5. android 绘图 双缓存,Android开发之用双缓冲技术绘图
  6. WEG的完整形式是什么?
  7. Django初次体验
  8. youcans 的 OpenCV 学习课—4.图像的叠加与混合
  9. 【面向对象】面向对象程序设计测试题2-Java基本语法测试题
  10. 神经网络进行自然语言处理最佳实践
  11. 课堂破冰游戏“猜猜他是谁”
  12. 【揭秘】中国四大银行的大数据应用已到了哪个阶段?
  13. Windows实现微信多开+美化图标
  14. 如何备考系统集成项目管理工程师?
  15. 『TensorFlow』pad图片
  16. 每天自我提升的8个好习惯
  17. 太强了!!!GNN + PLM→CIKM'22最佳论文
  18. 实操:基于LNMP搭建zabbix监控
  19. ubuntu 安装wifi驱动(Device-c822)
  20. 美国大学英语写作第9版_笔记1_概况

热门文章

  1. 如何读取yaml(yml)文件
  2. js 一串数字1403149534转换为日期格式
  3. ant design 预览图片_Ant Design Pro上传图片
  4. vlc播放g711 rtp流媒体sdp文件及其参数介绍
  5. APP消息推送测试点
  6. QImage 32bit转8bit
  7. 3D动作手游的辅助瞄准算法(二)
  8. 5 款最棒的 Vue 移动端 UI 组件库 - 特别针对国内使用场景推荐
  9. Linux内核源码分析-scsi子系统-让磁盘转起来-sd_spinup_disk
  10. 无需编程,DIY自己智能小车的Android蓝牙遥控软件(一)