浅谈javascript中的闭包


Posted in Javascript onMay 13, 2015

很长一段时间不理解闭包,后来了解了作用域,以及this相关问题才理解了闭包相关知识。
闭包(closure),也是面试题常客。简单点来说就是函数嵌套函数。

函数作为返回值:

function foo () {
  var a = 1;
  return function () {
   a++;
   console.log(a);
  }
}
var aaa = foo();
aaa(); //2
aaa(); //3

其实这个代码不难理解,aaa是指向foo()返回的一个新函数,但是在这个函数里面引用了a变量,所以当执行完foo函数时,变量a还存在内存中不释放。即a分别为2和3。

函数作为参数:

var a = 10;
function foo () {
console.log(a);
}
function aaa(fn) {
 var a = 100;
 fn();
}
aaa(foo);

按照我以前的理解,当执行在aaa函数里面执行fn函数,那么如果自身没有a变量,就去父级作用域找a变量,此处是100,那结果是100吗?

可惜答案不是,在这里结果是10,王福朋老师的博客讲的比较好,他说要去创建这个函数的作用域取值,而不是“父作用域”。

闭包的使用场景

因为本人还比较菜鸟,在这里取一个简单例子。当点击li的时候弹出li在ul中所处的位置即索引值。

html代码:

<ul>
  <li>001</li>
  <li>002</li>
  <li>003</li>
</ul>

js代码:

示例 1:
请看下面的代码,运行后发现,无论点击那个li,结果都是3了。

var aLi = document.getElementsByTagName('li');
for (var i = 0; i<aLi.length; i++) {
  aLi[i].onclick = function() {
   alert(i);
  }
}

因为在匿名函数里面并没有i变量,所以当for结束后,我们再去点击页面的li标签,此时i早就是3了。

示例 2:

aLi[i].onclick = (function(i){
    return function(){
      alert(i);
    }
  })(i);

这次的做法是把函数当返回值,通过自执行函数的参数,把变量i传进去,然后因为返回函数要引用这个i变量,所以当for循环结束也不会释放i变量。即在内存中保存了i变量的值。基于这样的原理,很容易在低版本ie中造成内存泄露。

示例 3:

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

这个原理和上面大同小异。

小米前端闭包面试题:

function repeat (func, times, wait) {
} //这个函数能返回一个新函数,比如这样用

var repeatedFun = repeat(alert, 10, 5000)
//调用这个 repeatedFun ("hellworld")

//会alert十次 helloworld, 每次间隔5秒

我的答案:

function repeat (func, times, wait) {
  return function(str) {
    while (times >0) {
      setTimeout(function(){
        func(str);
      },wait);
      times--;
    }
  }
}

var repeatedFun = repeat(alert, 10, 100);
repeatedFun ("hellworld");

以上所述就是本文的全部内容了,希望对大家学习javascript闭包能够有所帮助。

Javascript 相关文章推荐
JavaScript中valueOf函数与toString方法深入理解
Dec 02 Javascript
jQuery中:hidden选择器用法实例
Dec 30 Javascript
javascript获取四位数字或者字母的随机数
Jan 09 Javascript
JS 事件绑定、事件监听、事件委托详细介绍
Sep 28 Javascript
浅谈JavaScript的函数及作用域
Dec 30 Javascript
对比分析Django的Q查询及AngularJS的Datatables分页插件
Feb 07 Javascript
Bootstrap 网格系统布局详解
Mar 19 Javascript
Angular2 组件交互实例详解
Aug 24 Javascript
Vuejs 2.0 子组件访问/调用父组件的方法(示例代码)
Feb 08 Javascript
javascript中的数据类型检测方法详解
Aug 07 Javascript
axios如何利用promise无痛刷新token的实现方法
Aug 27 Javascript
浅谈JS的二进制家族
May 09 Javascript
jQuery构造函数init参数分析续
May 13 #Javascript
jQuery构造函数init参数分析
May 13 #Javascript
CSS+JS实现点击文字弹出定时自动关闭DIV层菜单的方法
May 12 #Javascript
JavaScript实现DIV层拖动及动态增加新层的方法
May 12 #Javascript
js实现带按钮的上下滚动效果
May 12 #Javascript
js验证上传图片的方法
May 12 #Javascript
js中setTimeout()与clearTimeout()用法实例浅析
May 12 #Javascript
You might like
php实现图片局部打马赛克的方法
2015/02/11 PHP
thinkPHP3.1验证码的简单实现方法
2016/04/22 PHP
Zend Framework处理Json数据方法详解
2016/12/09 PHP
yii2 resetful 授权验证详解
2017/05/18 PHP
关于恒等于(===)和非恒等于(!==)
2007/08/20 Javascript
js的touch事件的实际引用
2014/10/13 Javascript
实例解析jQuery中proxy()函数的用法
2016/05/24 Javascript
浅谈JavaScript的自动垃圾收集机制
2016/12/15 Javascript
基于vue实现多引擎搜索及关键字提示
2017/03/16 Javascript
基于JS实现仿京东搜索栏随滑动透明度渐变效果
2017/07/10 Javascript
JsChart组件使用详解
2018/03/04 Javascript
vue2.0 循环遍历加载不同图片的方法
2018/03/06 Javascript
webpack 插件html-webpack-plugin的具体使用
2018/04/09 Javascript
javascript实现计算指定范围内的质数示例
2018/12/29 Javascript
vue3.0 搭建项目总结(详细步骤)
2019/05/20 Javascript
零基础写python爬虫之抓取糗事百科代码分享
2014/11/06 Python
Python中编写ORM框架的入门指引
2015/04/29 Python
举例讲解Python的lambda语句声明匿名函数的用法
2016/07/01 Python
Python抓取框架Scrapy爬虫入门:页面提取
2017/12/01 Python
python去除文件中重复的行实例
2018/06/29 Python
python 用opencv调用训练好的模型进行识别的方法
2018/12/07 Python
pytorch GAN生成对抗网络实例
2020/01/10 Python
python pptx复制指定页的ppt教程
2020/02/14 Python
Python pexpect模块及shell脚本except原理解析
2020/08/03 Python
python re模块常见用法例举
2021/03/01 Python
世界上最值得信赖的多日游在线市场:TourRadar
2018/07/20 全球购物
Ivory Isle Designs美国/加拿大:婚礼和活动文具公司
2018/08/21 全球购物
酒店前台接待岗位职责
2013/12/03 职场文书
社会实践活动总结报告
2014/04/29 职场文书
材料成型及控制工程专业求职信
2014/06/19 职场文书
四风剖析查摆对照检查材料思想汇报
2014/09/24 职场文书
庆七一宣传标语
2014/10/08 职场文书
2014年团委工作总结
2014/11/13 职场文书
纪录片信仰观后感
2015/06/08 职场文书
python 使用Tensorflow训练BP神经网络实现鸢尾花分类
2021/05/12 Python
JS如何实现基于websocket的多端桥接平台
2021/05/14 Javascript