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 相关文章推荐
jquery解析xml字符串简单示例
Apr 11 Javascript
jQuery实现浮动层随浏览器滚动条滚动的方法
Sep 22 Javascript
JQuery.Ajax()的data参数类型实例详解
Nov 20 Javascript
新手学习前端之js模仿淘宝主页网站
Oct 31 Javascript
JS编写函数实现对身份证号码最后一位的验证功能
Dec 29 Javascript
JS实现动态给标签控件添加事件的方法示例
May 13 Javascript
微信小程序 swiper组件构建轮播图的实例
Sep 20 Javascript
JS和JQuery实现雪花飘落效果
Nov 30 jQuery
vue实现在一个方法执行完后执行另一个方法的示例
Aug 25 Javascript
小程序如何定位所在城市及发起周边搜索
Feb 11 Javascript
详解node.js 事件循环
Jul 22 Javascript
JavaScript 反射学习技巧
Oct 16 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
php adodb连接不同数据库
2009/03/19 PHP
深入PHP empty(),isset(),is_null()的实例测试详解
2013/06/06 PHP
PHP扩展程序实现守护进程
2015/04/16 PHP
PHP创建单例后台进程的方法示例
2017/05/23 PHP
phpStudy配置多站点多域名和多端口的方法
2017/09/01 PHP
一些不错的js函数ajax
2008/08/20 Javascript
利用google提供的API(JavaScript接口)获取网站访问者IP地理位置的代码详解
2010/07/24 Javascript
详谈javascript中DOM的基本属性
2015/02/26 Javascript
Node.js中Request模块处理HTTP协议请求的基本使用教程
2016/03/31 Javascript
获取当前月(季度/年)的最后一天(set相关操作及应用)
2016/12/27 Javascript
微信小程序 textarea 组件详解及简单实例
2017/01/10 Javascript
bootstrap IE8 兼容性处理
2017/03/22 Javascript
详解Vue中使用v-for语句抛出错误的解决方案
2017/05/04 Javascript
vue项目webpack中Npm传递参数配置不同域名接口
2018/06/15 Javascript
bootstrap下拉框动态赋值方法
2018/08/10 Javascript
微信小程序自定义带价格显示日历效果
2018/12/29 Javascript
微信小程序蓝牙连接小票打印机实例代码详解
2019/06/03 Javascript
jQuery实现简易聊天框
2020/02/08 jQuery
jQuery实现简单聊天室
2020/02/08 jQuery
Threejs实现滴滴官网首页地球动画功能
2020/07/13 Javascript
[01:02:54]完美世界DOTA2联赛PWL S2 FTD vs GXR 第一场 11.22
2020/11/26 DOTA
Pycharm学习教程(2) 代码风格
2017/05/02 Python
利用Python查看目录中的文件示例详解
2017/08/28 Python
python 多线程中子线程和主线程相互通信方法
2018/11/09 Python
django框架实现一次性上传多个文件功能示例【批量上传】
2019/06/19 Python
伦敦一家领先的精品零售商:IRIS Fashion
2019/05/24 全球购物
英国婚礼商城:Wedding Mall
2019/11/02 全球购物
大学生关于奋斗的演讲稿
2014/01/09 职场文书
迅雷Cued工作心得体会
2014/01/27 职场文书
公司薪酬管理制度
2014/01/31 职场文书
预备党员个人总结
2015/02/14 职场文书
法院执行局工作总结
2015/08/11 职场文书
2016春季小学开学寄语
2015/12/03 职场文书
Java中的随机数Random
2022/03/17 Java/Android
Java实现HTML转为Word的示例代码
2022/06/28 Java/Android
Java使用HttpClient实现文件下载
2022/08/14 Java/Android