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学习(二)javascript常见问题总结
Jan 02 Javascript
使用js画图之正弦曲线
Jan 12 Javascript
JavaScript将数字转换成大写中文的方法
Mar 23 Javascript
在JavaScript中使用NaN值的方法
Jun 05 Javascript
JavaScript实现的简单烟花特效代码
Oct 20 Javascript
AngularJS 执行流程详细介绍
Aug 18 Javascript
微信小程序 for 循环详解
Oct 09 Javascript
浅谈Javascript中的Label语句
Dec 14 Javascript
javascript实现秒表计时器的制作方法
Feb 16 Javascript
js中setTimeout的妙用--防止循环超时
Mar 06 Javascript
基于vue的换肤功能的示例代码
Oct 10 Javascript
vue实践---vue不依赖外部资源实现简单多语操作
Sep 21 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
5.PHP的其他功能
2006/10/09 PHP
php学习笔记 面向对象的构造与析构方法
2011/06/13 PHP
codeigniter框架The URI you submitted has disallowed characters错误解决方法
2014/05/06 PHP
PHP常用技巧汇总
2016/03/04 PHP
php通过文件头判断格式的方法
2016/05/28 PHP
layui框架实现文件上传及TP3.2.3(thinkPHP)对上传文件进行后台处理操作示例
2018/05/12 PHP
PHP attributes()函数讲解
2019/02/03 PHP
利用js对象弹出一个层
2008/03/26 Javascript
jquery中对表单的基本操作代码
2010/07/29 Javascript
javascript 词法作用域和闭包分析说明
2010/08/12 Javascript
js 链式延迟执行DOME
2012/01/04 Javascript
根据邮箱的域名跳转到相应的登录页面的代码
2012/02/27 Javascript
Knockout text绑定DOM的使用方法
2013/11/15 Javascript
深入理解jQuery中live与bind方法的区别
2013/12/18 Javascript
动态显示可输入的字数提示还可以输入的字数
2014/04/01 Javascript
跟我学习javascript的函数和函数表达式
2015/11/16 Javascript
javascript从定义到执行 你不知道的那些事
2016/01/04 Javascript
每日十条JavaScript经验技巧(二)
2016/06/23 Javascript
终于实现了!精彩的jquery弹幕效果
2016/07/18 Javascript
详解vue-Resource(与后端数据交互)
2017/01/16 Javascript
vue-resourse将json数据输出实例
2017/03/08 Javascript
微信小程序上传图片功能(附后端代码)
2020/06/19 Javascript
JS函数节流和防抖之间的区分和实现详解
2019/01/11 Javascript
原来JS还可以这样拆箱转换详解
2019/02/01 Javascript
Python计算字符宽度的方法
2016/06/14 Python
Python遍历某目录下的所有文件夹与文件路径
2018/03/15 Python
python 获取当天凌晨零点的时间戳方法
2018/05/22 Python
将Django项目部署到CentOs服务器中
2018/10/18 Python
老生常谈python中的重载
2018/11/11 Python
python3实现名片管理系统
2020/11/29 Python
Booking.com美国:全球酒店预订网站
2017/04/18 全球购物
美国知名珠宝首饰品牌:Gemvara
2017/10/06 全球购物
2015年度绩效考核工作总结
2015/05/27 职场文书
烛光里的微笑观后感
2015/06/17 职场文书
python 中[0]*2与0*2的区别说明
2021/05/10 Python
使用Python脚本对GiteePages进行一键部署的使用说明
2021/05/27 Python