轻松理解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 相关文章推荐
Javascript 判断客户端浏览器类型代码
Mar 01 Javascript
Javascript 中的 &amp;&amp; 和 || 使用小结
Apr 25 Javascript
JS.findElementById()使用介绍
Sep 21 Javascript
JS嵌套函数调用上下文的问题解决
Mar 26 Javascript
AngularJS基础知识笔记之表格
May 10 Javascript
详解JavaScript的回调函数
Nov 20 Javascript
微信小程序 教程之wxapp视图容器 scroll-view
Oct 19 Javascript
在vue-cli脚手架中配置一个vue-router前端路由
Jul 03 Javascript
在vue中v-bind使用三目运算符绑定class的实例
Sep 29 Javascript
微信小程序之裁剪图片成圆形的实现代码
Oct 11 Javascript
Jquery遍历筛选数组的几种方法和遍历解析json对象,Map()方法详解以及数组中查询某值是否存在
Jan 18 jQuery
js 获取本周、上周、本月、上月、本季度、上季度的开始结束日期
Feb 01 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
PHP中Fatal error session_start()错误解决步骤
2014/08/05 PHP
PHP中new static()与new self()的区别异同分析
2014/08/22 PHP
基于ThinkPHP实现批量删除
2015/12/18 PHP
PHP中set_include_path()函数相关用法分析
2016/07/18 PHP
php session的应用详细介绍
2017/03/22 PHP
yii2多图上传组件的使用教程
2018/05/10 PHP
php二维数组按某个键值排序的实例讲解
2019/02/15 PHP
thinkPHP+mysql+ajax实现的仿百度一下即时搜索效果详解
2019/07/15 PHP
PHP实现创建一个RPC服务操作示例
2020/02/23 PHP
JQuery中serialize()、serializeArray()和param()方法示例介绍
2014/07/31 Javascript
第二章之Bootstrap 页面排版样式
2016/04/25 Javascript
ES6新特性之Symbol类型用法分析
2017/03/31 Javascript
JS实现移动端按首字母检索城市列表附源码下载
2017/07/05 Javascript
详解Angular Reactive Form 表单验证
2017/07/06 Javascript
vue打包使用Nginx代理解决跨域问题
2018/08/27 Javascript
小程序实现展开/收起的效果示例
2018/09/22 Javascript
深入解析ES6中的promise
2018/11/08 Javascript
npm 常用命令详解(小结)
2019/01/17 Javascript
JS对象和字符串之间互换操作实例分析
2019/02/02 Javascript
详解vue-cli+es6引入es5写的js(两种方法)
2019/04/19 Javascript
koa+mongoose实现简单增删改查接口的示例代码
2019/05/13 Javascript
vue+koa2实现session、token登陆状态验证的示例
2019/08/30 Javascript
Vue打包后访问静态资源路径问题
2019/11/08 Javascript
[46:40]VGJ.T vs Winstrike 2018国际邀请赛小组赛BO2 第一场 8.17
2018/08/20 DOTA
Python中实现三目运算的方法
2015/06/21 Python
Python中标准模块importlib详解
2017/04/16 Python
关于python2 csv写入空白行的问题
2018/06/22 Python
Pycharm简单使用教程(入门小结)
2019/07/04 Python
浅谈tensorflow中Dataset图片的批量读取及维度的操作详解
2020/01/20 Python
基于tensorflow for循环 while循环案例
2020/06/30 Python
HTML如何让IMG自动适应DIV容器大小的实现方法
2020/02/25 HTML / CSS
探索欧洲最好的品牌:Bombinate
2019/06/14 全球购物
应届生妇产科护士求职信
2013/10/27 职场文书
会计出纳员的自我评价
2014/01/15 职场文书
企业指导教师评语
2014/04/28 职场文书
华为HarmonyOS3.0强在哪? 看看鸿蒙3.0这7个小功能
2023/01/09 数码科技