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 setattribute批量设置css样式
Nov 26 Javascript
Jquery Ajax学习实例4 向WebService发出请求,返回实体对象的异步调用
Mar 16 Javascript
封装的原生javascript弹出层代码
Sep 24 Javascript
腾讯的ip接口 方便获取当前用户的ip地理位置
Nov 25 Javascript
javascript获取wx.config内部字段解决微信分享
Mar 09 Javascript
如何让一个json文件显示在表格里【实现代码】
May 09 Javascript
浅析JavaScript函数的调用模式
Aug 10 Javascript
JavaScript事件用法浅析
Oct 31 Javascript
浅谈webpack组织模块的原理
Mar 10 Javascript
JS实现左边列表移到到右边列表功能
Mar 28 Javascript
在vant中使用时间选择器和popup弹出层的操作
Nov 04 Javascript
解决nuxt 自定义全局方法,全局属性,全局变量的问题
Nov 05 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 GD 图像处理组件的常用函数总结
2010/04/28 PHP
浅谈PHP调用Webservice思路及源码分享
2014/06/04 PHP
PHP实现的QQ空间g_tk加密算法
2015/07/09 PHP
PHP实现负载均衡下的session共用功能
2018/04/17 PHP
JSON扫盲帖 JSON.as类教程
2009/02/16 Javascript
jquery下操作HTML控件的实现代码
2010/01/12 Javascript
javascript中注册和移除事件的4种方式
2013/03/20 Javascript
Jquery获得控件值的三种方法总结
2014/02/13 Javascript
jquery禁止输入数字以外的字符的示例(纯数字验证码)
2014/04/10 Javascript
jquery实现标签上移、下移、置顶
2015/04/26 Javascript
js中this用法实例详解
2015/05/05 Javascript
jquery trigger函数执行两次的解决方法
2016/02/29 Javascript
微信小程序图片选择、上传到服务器、预览(PHP)实现实例
2017/05/11 Javascript
详解10分钟学会vue滚动行为
2017/09/21 Javascript
vue2.0 父组件给子组件传递数据的方法
2018/01/15 Javascript
快速处理vue渲染前的显示问题
2018/03/05 Javascript
基于Vue中点击组件外关闭组件的实现方法
2018/03/06 Javascript
微信小程序form表单组件示例代码
2018/07/15 Javascript
vue中的router-view组件的使用教程
2018/10/23 Javascript
vue自定义指令实现仅支持输入数字和浮点型的示例
2019/10/30 Javascript
浅谈Node新版本13.2.0正式支持ES Modules特性
2019/11/25 Javascript
使用AutoJs实现微信抢红包的代码
2020/12/31 Javascript
[54:53]完美世界DOTA2联赛PWL S2 GXR vs PXG 第二场 11.18
2020/11/18 DOTA
Mac OS X10.9安装的Python2.7升级Python3.3步骤详解
2013/12/04 Python
python使用datetime模块计算各种时间间隔的方法
2015/03/24 Python
深入理解Python中的super()方法
2017/11/20 Python
vscode 远程调试python的方法
2017/12/01 Python
python利用selenium进行浏览器爬虫
2019/04/25 Python
Django修改app名称和数据表迁移方案实现
2020/09/17 Python
opencv python 对指针仪表读数识别的两种方式
2021/01/14 Python
马来西亚和新加坡巴士票在线预订:CatchThatBus
2018/11/17 全球购物
文化建设工作方案
2014/05/12 职场文书
2014最新毕业证代领委托书
2014/09/26 职场文书
2014光棍节单身联谊活动策划书
2014/10/10 职场文书
四风专项整治工作情况汇报
2014/10/28 职场文书
建筑质检员岗位职责
2015/04/08 职场文书