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事件列表解说
Dec 22 Javascript
javascript 获取url参数和script标签中获取url参数函数代码
Jan 22 Javascript
关于jQuery object and DOM element
Apr 15 Javascript
jQuery div拖拽用法实例
Jan 14 Javascript
Bootstrap编写导航栏和登陆框
May 30 Javascript
Javascript 实现放大镜效果实例详解
Dec 03 Javascript
jQuery Validate插件自定义验证规则的方法
Dec 27 Javascript
layui分页效果实现代码
May 19 Javascript
关于jQuery里prev()的简单操作代码
Oct 27 jQuery
关于JavaScript语句后面的分号问题
Dec 07 Javascript
js实现轮播图效果 z-index实现轮播图
Jan 17 Javascript
node 版本切换的实现
Feb 02 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
8个出色的WordPress SEO插件收集
2011/02/26 PHP
最新用php获取谷歌PR值算法,附上php查询PR值代码示例
2011/12/25 PHP
PHP实现将浏览历史页面网址保存到cookie的方法
2015/01/26 PHP
php函数mkdir实现递归创建层级目录
2016/10/27 PHP
thinkPHP5框架自定义验证器实现方法分析
2018/06/11 PHP
PHP延迟静态绑定使用方法实例解析
2020/09/05 PHP
javascript 面向对象,实现namespace,class,继承,重载
2009/10/29 Javascript
Jquery validation remote 验证的缓存问题解决方法
2014/03/25 Javascript
深入理解JavaScript系列(17):面向对象编程之概论详细介绍
2015/03/04 Javascript
JavaScript记录光标在编辑器中位置的实现方法
2016/04/22 Javascript
js实现的万能flv网页播放器代码
2016/04/30 Javascript
JS选取DOM元素的简单方法
2016/07/08 Javascript
原生js实现键盘控制div移动且解决停顿问题
2016/12/05 Javascript
Angular.JS通过指令操作DOM的方法
2017/05/10 Javascript
jQuery实现上传图片前预览效果功能
2017/08/03 jQuery
详解webpack babel的配置
2018/01/09 Javascript
vue中实现在外部调用methods的方法(推荐)
2018/02/08 Javascript
原生JS实现的雪花飘落动画效果
2018/05/03 Javascript
一步快速解决微信小程序中textarea层级太高遮挡其他组件
2019/03/04 Javascript
vue-cli脚手架打包静态资源请求出错的原因与解决
2019/06/06 Javascript
JS中FileReader类实现文件上传及时预览功能
2020/03/27 Javascript
解决antd 表单设置默认值initialValue后验证失效的问题
2020/11/02 Javascript
python将图片文件转换成base64编码的方法
2015/03/14 Python
Python实现获取照片拍摄日期并重命名的方法
2017/09/30 Python
django与vue的完美结合_实现前后端的分离开发之后在整合的方法
2019/08/12 Python
Python+Xlwings 删除Excel的行和列
2020/12/19 Python
CSS3制作炫酷带方向感应的鼠标滑过图片3D动画
2016/03/16 HTML / CSS
英国骑行、跑步、游泳、铁人三项运动装备专卖店:Wiggle
2016/08/23 全球购物
adidas美国官网:adidas US
2016/09/21 全球购物
大学专科自荐信
2014/06/17 职场文书
作风转变心得体会
2014/09/02 职场文书
公司离职证明范本(汇总)
2014/09/10 职场文书
四风问题个人自查剖析材料思想汇报
2014/09/21 职场文书
中学生学习保证书
2015/02/26 职场文书
2015年结对帮扶工作总结
2015/05/04 职场文书
Python-typing: 类型标注与支持 Any类型详解
2021/05/10 Python