轻松理解JavaScript闭包


Posted in Javascript onMarch 14, 2017

摘要

闭包机制是JavaScript的重点和难点,本文希望能帮助大家轻松的学习闭包

一、什么是闭包?

闭包就是可以访问另一个函数作用域中变量的函数。

下面列举出常见的闭包实现方式,以例子讲解闭包概念

function f1(){

var n=999;


nAdd=function(){n+=1}


function f2(){



alert(n);


}


return f2;

}

var result=f1();

result(); // 999

nAdd();

result(); // 1000

f1是f2的父函数,而f2被赋给了一个全局变量(return的值),这导致f2始终在内存中,而f2的存在依赖于f1,因此f1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收,这便形成了闭包。

因此,可以这么理解。闭包机制就是,如果A函数引用了另一个函数B的变量,但是B返回后A仍没有返回,仍存在,因为A的引用,所以B的所有局部变量并不会随B退出而注销,会一直存在,直到A注销。此时A就是闭包。

二、闭包的this指针

闭包通常在全局环境调用的,所以this通常指向window,具体情况还是需要视执行环境而言,总之this指向执行环境。

若需要闭包的this指向闭包的包含对象,则需要将包含对象的this作为变量传进闭包。

三、使用闭包的注意点

  1. 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
  2. 闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。

四、解决一道闭包常见面试题

问题:

function onMyLoad(){
  /*
  抛出问题:
  此题的目的是想每次点击对应目标时弹出对应的数字下标 0~4,但实际是无论点击哪个目标都会弹出数字5
  问题所在:
  arr 中的每一项的 onclick 均为一个函数实例(Function 对象),这个函数实例也产生了一个闭包域,
  这个闭包域引用了外部闭包域的变量,其 function scope 的 closure 对象有个名为 i 的引用,
  外部闭包域的私有变量内容发生变化,内部闭包域得到的值自然会发生改变
  */
  var arr = document.getElementsByTagName("p");
  for(var i = 0; i < arr.length;i++){
  arr[i].onclick = function(){
   alert(i);
  }
  }
 }

解决方法

1、在外面再加一层函数,将i作为函数参数传进来,这样每次保存的是函数内部的变量,与外部i不是同一个内存空间,而每次调用函数都会生成一个局部变量,所以可以保证每次保存的值互不影响。

for(var i = 0; i<arr.length;i++){
 arr[i].onclick = (function(arg){
  return function () {
   alert(arg);
  }
 })(i);
}

2、用ES6新特let,将for循环的var i改成let i,这样当前的i只在本轮循环有效,所以每一次循环的i其实都是一个新的变量。你可能会问,如果每一轮循环的变量i都是重新声明的,那它怎么知道上一轮循环的值,从而计算出本轮循环的值?这是因为 JavaScript 引擎内部会记住上一轮循环的值,初始化本轮的变量i时,就在上一轮循环的基础上进行计算。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

Javascript 相关文章推荐
extjs每个组件要设置唯一的ID否则会出错
Jun 15 Javascript
javascript制作游戏开发碰撞检测的封装代码
Mar 31 Javascript
js+html5实现canvas绘制简单矩形的方法
Jun 05 Javascript
jQuery移动页面开发中的触摸事件与虚拟鼠标事件简介
Dec 03 Javascript
JS实现左右无缝轮播图代码
May 01 Javascript
jQuery AJAX timeout 超时问题详解
Jun 21 Javascript
JS中append字符串包含onclick无效传递参数失败的解决方案
Dec 26 Javascript
Angularjs自定义指令实现分页插件(DEMO)
Sep 16 Javascript
将Sublime Text 3 添加到右键中的简单方法
Dec 12 Javascript
基于casperjs和resemble.js实现一个像素对比服务详解
Jan 10 Javascript
对TypeScript库进行单元测试的方法
Jul 18 Javascript
JavaScript实现多个物体同时运动
Mar 12 Javascript
微信小程序 页面跳转及数据传递详解
Mar 14 #Javascript
JavaScript ES6中export、import与export default的用法和区别
Mar 14 #Javascript
微信小程序 动态绑定数据及动态事件处理
Mar 14 #Javascript
Vue 2.0+Vue-router构建一个简单的单页应用(附源码)
Mar 14 #Javascript
vuejs响应用户事件(如点击事件)
Mar 14 #Javascript
微信小程序 在线支付功能的实现
Mar 14 #Javascript
JS和canvas实现俄罗斯方块
Mar 14 #Javascript
You might like
php5中date()得出的时间为什么不是当前时间的解决方法
2008/06/30 PHP
浅谈PHP解析URL函数parse_url和parse_str
2014/11/11 PHP
使用PHP和JavaScript判断请求是否来自微信内浏览器
2015/08/18 PHP
php封装的图片(缩略图)处理类完整实例
2016/10/19 PHP
利用PHPExcel实现Excel文件的写入和读取
2017/04/26 PHP
用javascript实现的支持lrc歌词的播放器
2007/05/17 Javascript
Mootools 1.2教程 事件处理
2009/09/15 Javascript
Javascript string 扩展库代码
2010/04/09 Javascript
JavaScript(js)设置默认输入焦点(focus)
2012/12/28 Javascript
JQuery插件fancybox无法在弹出层使用左右键的解决办法
2013/12/25 Javascript
javascript 3d 逐侦产品展示(核心精简)
2014/03/26 Javascript
js实现按一下删除键删除整个单词附demo
2014/09/05 Javascript
JavaScript不刷新实现浏览器的前进后退功能
2014/11/05 Javascript
jQuery中parents()方法用法实例
2015/01/07 Javascript
D3.js进阶系列之CSV表格文件的读取详解
2017/06/06 Javascript
Flutter实现仿微信底部菜单栏功能
2019/09/18 Javascript
python版本的读写锁操作方法
2016/04/25 Python
详解python OpenCV学习笔记之直方图均衡化
2018/02/08 Python
Python实现的爬虫刷回复功能示例
2018/06/07 Python
为何人工智能(AI)首选Python?读完这篇文章你就知道了(推荐)
2019/04/06 Python
python3实现高效的端口扫描
2019/08/31 Python
python实现大战外星人小游戏实例代码
2019/12/26 Python
快速解决Django关闭Debug模式无法加载media图片与static静态文件
2020/04/07 Python
python继承threading.Thread实现有返回值的子类实例
2020/05/02 Python
Keras 利用sklearn的ROC-AUC建立评价函数详解
2020/06/15 Python
中东最大的在线宠物店:Dubai Pet Food
2020/06/11 全球购物
幼儿园毕业典礼主持词
2014/03/21 职场文书
员工考核评语大全
2014/04/26 职场文书
廉洁教育学习材料
2014/05/19 职场文书
处级干部考察材料
2014/12/24 职场文书
2015大学生求职信范文
2015/03/20 职场文书
现货白银电话营销话术
2015/05/29 职场文书
2016幼儿园中班开学寄语
2015/12/03 职场文书
Python 中random 库的详细使用
2021/06/03 Python
Python中rapidjson参数校验实现
2021/07/25 Python
海弦WR-800F
2022/04/05 无线电