js核心基础之闭包的应用实例分析


Posted in Javascript onMay 11, 2019

本文实例讲述了js闭包的应用。分享给大家供大家参考,具体如下:

需求:有一个列表,当点击哪一行,则显示当前是第几行。

html代码:

<p>第一行</p>
<p>第二行</p>
<p>第三行</p>

错误js代码示范:

function addHander(nodes){
  for ( var i=0;i<nodes.length;i++) {
    var node=nodes[i];
    node.onclick=function(){
     alert('当前是第'+i+'行');//3 3 3
    }
  }
}
var nodes=document.getElementsByTagName("p");
addHander( nodes);

从逻辑上来看,毫无漏洞,对不对?

但是,当你每次点击的时候,弹出的都是最后一行。

原理:当页面加载完成之后就调用addHandler函数,为每个节点绑定点击事件处理函数,绑定的是匿名函数,但是,这时候node上的匿名函数并没有被调用,所以,当for循环完成之后i已经等于3了,当你点击节点时,调用匿名函数所以弹出的就是3了。

解决方法一:

function addHandler(nodes) {
 function invoke(i) {
   return **function () {
     alert(i+1);
   }**
 }
 for (var i=0;i<nodes.length;i++){
   var node=nodes[i];
   node.onclick=invoke(i);
 }
}
var nodes=document.getElementsByTagName("p");
addHandler( nodes);

原理:当addHandler函数被调用之后,节点同样被绑定了点击事件处理函数,但是,这时后绑定的是invoke函数返回的匿名函数(function (i){ alert (i+1) }),我们可以想象一下,当点击节点时,调用invoke函数返回的匿名函数,并且将i作为参数传过去,这时候这个I则是当前点击节点的索引下标,所以,弹出的应该是i+1;

解决方法二:

function addHandler(nodes){
  for ( var i=0;i<nodes.length;i++) {
    var node=nodes[i];
    node.onclick=**function(j){
    //同样的返回的均为函数,但匿名函数自调用将其激活了
      return *function(){//闭包
        alert(j+1);
      }*
    }(i);**
  }
}
var nodes=document.getElementsByTagName("p");
addHandler(nodes);

原理:

绑定的也是一个匿名函数,但是外层的匿名函数(见粗体)自调用激活了,返回的同样是个匿名函数(见斜体),这个匿名函数则是要等到点击之后才被调用,这时,弹出的同样是当前节点的索引下标+1.

若是感觉自己已经理解,但是又没办法验证,这里有个练习题,可以试试。

function f(){
  var a=[];
  for ( var i=0;i<3;i++) {
    a[i]=function(){
      return i*2;
    }
  }
  return a;
}
var result=f();
document.write(result[0]()+result[1]()+result[2]());
//输出为6  6  6

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
JS 非图片动态loading效果实现代码
Apr 09 Javascript
jquery获取input表单值的代码
Apr 19 Javascript
JS创建类和对象的两种不同方式
Aug 08 Javascript
javascript引用类型之时间Date和数组Array
Aug 27 Javascript
JavaScript实现给定时间相加天数的方法
Jan 25 Javascript
Bootstrap弹出框(modal)垂直居中的问题及解决方案详解
Jun 12 Javascript
JS正则验证多个邮箱完整实例【邮箱用分号隔开】
Apr 19 Javascript
基于jQuery实现文字打印动态效果
Apr 21 jQuery
react-native ListView下拉刷新上拉加载实现代码
Aug 03 Javascript
label+input实现按钮开关切换效果的实例
Aug 16 Javascript
JQuery实现table中tr上移下移的示例(超简单)
Jan 08 jQuery
Vue实现base64编码图片间的切换功能
Dec 04 Javascript
vue下载excel的实现代码后台用post方法
May 10 #Javascript
微信小程序如何再次获取用户授权的方法
May 10 #Javascript
vue 弹窗时 监听手机返回键关闭弹窗功能(页面不跳转)
May 10 #Javascript
vue-cli+axios实现文件上传下载功能(下载接收后台返回文件流)
May 10 #Javascript
vue element中axios下载文件(后端Python)
May 10 #Javascript
微信小程序授权登录解决方案的代码实例(含未通过授权解决方案)
May 10 #Javascript
简单通过settimeout看javascript的运行机制
May 10 #Javascript
You might like
初学CAKEPHP 基础教程
2009/11/02 PHP
php启用zlib压缩文件的配置方法
2013/06/12 PHP
PHP FTP操作类代码( 上传、拷贝、移动、删除文件/创建目录)
2014/05/10 PHP
thinkphp5.1框架模板布局与模板继承用法分析
2019/07/19 PHP
Prototype使用指南之ajax
2007/01/10 Javascript
javascript 定义初始化数组函数
2009/09/07 Javascript
js 内存释放问题
2010/04/25 Javascript
改善用户体验的五款jQuery插件分享
2011/05/22 Javascript
IFrame跨域高度自适应实现代码
2012/08/16 Javascript
jquery中选择块并改变属性值的方法
2013/07/31 Javascript
event对象获取方法总结在google浏览器下测试
2013/11/03 Javascript
借助javascript代码判断网页是静态还是伪静态
2014/05/05 Javascript
用jquery的方法制作一个简单的导航栏
2014/06/23 Javascript
原生JS绑定滑轮滚动事件兼容常见浏览器
2014/06/30 Javascript
js取得html iframe中的元素和变量值
2014/06/30 Javascript
jQuery中append()方法用法实例
2014/12/25 Javascript
jQuery实现鼠标单击网页文字后在文本框显示的方法
2015/05/06 Javascript
JavaScript的设计模式经典之建造者模式
2016/02/24 Javascript
js数字滑动时钟的简单实现(示例讲解)
2017/08/14 Javascript
浅谈Vue内置component组件的应用场景
2018/03/27 Javascript
JS实现的合并多个数组去重算法示例
2018/04/11 Javascript
跟混乱的页面弹窗说再见
2019/04/11 Javascript
Vue自定义多选组件使用详解
2020/09/08 Javascript
vue+element UI实现树形表格
2020/12/29 Vue.js
python中日志logging模块的性能及多进程详解
2017/07/18 Python
python中利用Future对象回调别的函数示例代码
2017/09/07 Python
学python安装的软件总结
2019/10/12 Python
基于注解实现 SpringBoot 接口防刷的方法
2021/03/02 Python
国际知名设计师时装商店:Coggles
2016/09/05 全球购物
SQL Server面试题
2013/04/04 面试题
庆八一活动方案
2014/01/25 职场文书
计算机通信专业推荐信
2014/02/22 职场文书
精神文明建设汇报材料
2014/12/24 职场文书
节约用电倡议书
2015/04/28 职场文书
话题作文之关于呼唤
2019/11/29 职场文书
解决MySQL存储时间出现不一致的问题
2021/04/28 MySQL