浅谈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 相关文章推荐
JsEasy简介 JsEasy是什么?与下载
Mar 07 Javascript
js中的前绑定和后绑定详解
Aug 01 Javascript
JQuery做的一个简单的点灯游戏分享
Jul 16 Javascript
EasyUI中实现form表单提交的示例分享
Mar 01 Javascript
jquery实现的Accordion折叠面板效果代码
Sep 02 Javascript
每天一篇javascript学习小结(面向对象编程)
Nov 20 Javascript
实例详解AngularJS实现无限级联动菜单
Jan 15 Javascript
JS验证input输入框(字母,数字,符号,中文)
Mar 23 Javascript
bootstrap Table插件使用demo
Aug 07 Javascript
基于jQuery选择器之表单对象属性筛选选择器的实例
Sep 19 jQuery
JavaScript Math对象和调试程序的方法分析
May 13 Javascript
JS自定义对象创建与简单使用方法示例
Jan 15 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
用文本文件制作留言板提示(上)
2006/10/09 PHP
Laravel框架使用Seeder实现自动填充数据功能
2018/06/13 PHP
jQuery 联动日历实现代码
2012/05/31 Javascript
js操作CheckBoxList实现全选/反选(在客服端完成)
2013/02/02 Javascript
JS输入用户名自动显示邮箱后缀列表的方法
2015/01/27 Javascript
简单纯js实现点击切换TAB标签实例
2015/08/23 Javascript
学习jQuey中的return false
2015/12/18 Javascript
浅谈js中子页面父页面方法 变量相互调用
2016/08/04 Javascript
JavaScript兼容性总结之获取非行间样式案例
2016/08/07 Javascript
bootstrap——bootstrapTable实现隐藏列的示例
2017/01/14 Javascript
Vue2.0 多 Tab切换组件的封装实例
2017/07/28 Javascript
JS添加或删除HTML dom元素的方法实例分析
2019/03/05 Javascript
VSCode使用之Vue工程配置eslint
2019/04/30 Javascript
vue+element实现打印页面功能
2019/05/20 Javascript
简述Python中的面向对象编程的概念
2015/04/27 Python
Python itertools模块详解
2015/05/09 Python
浅析Python的web.py框架中url的设定方法
2016/07/11 Python
Python numpy 提取矩阵的某一行或某一列的实例
2018/04/03 Python
详解Python下ftp上传文件linux服务器
2018/06/21 Python
python requests.post带head和body的实例
2019/01/02 Python
Python类的继承、多态及获取对象信息操作详解
2019/02/28 Python
Python类中方法getitem和getattr详解
2019/08/30 Python
Python数据可视化实现多种图例代码详解
2020/07/14 Python
HTML5新表单元素_动力节点Java学院整理
2017/07/12 HTML / CSS
南威尔士家居商店:Leekes
2016/10/25 全球购物
AJAX检测用户名是否存在的方法
2021/03/24 Javascript
日语求职信范文
2013/12/17 职场文书
《盘古开天地》教学反思
2014/02/28 职场文书
产品质量保证书
2014/04/29 职场文书
教师廉洁自律承诺书
2014/05/26 职场文书
应届生自荐信
2014/06/30 职场文书
单位委托书格式范本
2014/09/29 职场文书
春季运动会开幕词
2015/01/28 职场文书
工作一年自我鉴定
2019/06/20 职场文书
手把手教你实现PyTorch的MNIST数据集
2021/06/28 Python
Redis 操作多个数据库的配置的方法实现
2022/03/23 Redis