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 相关文章推荐
分析 JavaScript 中令人困惑的变量赋值
Aug 13 Javascript
jQuery代码优化 遍历篇
Nov 01 Javascript
jquery模拟SELECT下拉框取值效果
Oct 23 Javascript
jQuery通过点击行来删除HTML表格行的实现示例
Sep 10 Javascript
JS设置网页图片vspace和hspace属性的方法
Apr 01 Javascript
JavaScript生成二维码图片小结
Dec 27 Javascript
javascript中call,apply,bind函数用法示例
Dec 19 Javascript
浅析vue component 组件使用
Mar 06 Javascript
bootstrap时间插件daterangepicker使用详解
Oct 19 Javascript
微信小程序实现富文本图片宽度自适应的方法
Jan 20 Javascript
Node.js API详解之 tty功能与用法实例分析
Apr 27 Javascript
JavaScript架构搭建前端监控如何采集异常数据
Jun 25 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
10个实用的PHP代码片段
2011/09/02 PHP
thinkphp模板输出技巧汇总
2014/11/24 PHP
PHP简单实现冒泡排序的方法
2016/12/26 PHP
PHP实现简单登录界面
2019/10/23 PHP
节点的插入之append()和appendTo()的用法介绍
2014/01/13 Javascript
js实现网页标题栏闪烁提示效果实例分析
2014/11/20 Javascript
JavaScript的原型继承详解
2015/02/15 Javascript
nodejs爬虫抓取数据之编码问题
2015/07/03 NodeJs
javascript作用域问题实例分析
2015/07/13 Javascript
jquery+css实现绚丽的横向二级下拉菜单-附源码下载
2015/08/23 Javascript
JS根据key值获取URL中的参数值及把URL的参数转换成json对象
2015/08/26 Javascript
浅析jQuery移动开发中内联按钮和分组按钮的编写
2015/12/04 Javascript
Bootstrap每天必学之响应式导航、轮播图
2016/04/25 Javascript
jQuery实现的自动加载页面功能示例
2016/09/04 Javascript
AngularJS使用带属性值的ng-app指令实现自定义模块自动加载的方法
2017/01/04 Javascript
微信小程序 特效菜单抽屉效果实例代码
2017/01/11 Javascript
微信小程序 共用变量值的实现
2017/07/12 Javascript
JScript实现表格的简单操作
2017/08/15 Javascript
vue单页应用在页面刷新时保留状态数据的方法
2018/09/21 Javascript
[01:00:53]2018DOTA2亚洲邀请赛3月29日 小组赛B组 iG VS Secret
2018/03/30 DOTA
使用Python获取CPU、内存和硬盘等windowns系统信息的2个例子
2014/04/15 Python
Python中统计函数运行耗时的方法
2015/05/05 Python
Python中subprocess的简单使用示例
2015/07/28 Python
Python3编程实现获取阿里云ECS实例及监控的方法
2017/08/18 Python
Python中几种属性访问的区别与用法详解
2018/10/10 Python
python+selenium实现自动抢票功能实例代码
2018/11/23 Python
wxPython实现分隔窗口
2019/11/19 Python
用python写PDF转换器的实现
2020/10/29 Python
python UDF 实现对csv批量md5加密操作
2021/01/01 Python
解决CSS3的opacity属性带来的层叠顺序问题
2016/05/09 HTML / CSS
应届生保险求职信
2013/11/11 职场文书
给导游的表扬信
2014/01/10 职场文书
行政管理毕业生自荐信
2014/02/24 职场文书
关于五一放假的通知
2015/08/18 职场文书
2016国培学习心得体会
2016/01/08 职场文书
2016年师德学习心得体会
2016/01/12 职场文书