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 相关文章推荐
AlertBox 弹出层信息提示框效果实现步骤
Oct 11 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(五)可移动地图的实现
Jan 23 Javascript
js获取html页面节点方法(递归方式)
Dec 13 Javascript
jquery使用hide方法隐藏指定id的元素
Mar 30 Javascript
jquery实现的树形目录实例
Jun 26 Javascript
原生js实现tab选项卡切换
Mar 23 Javascript
javaScript基础详解
Jan 19 Javascript
深入理解Javascript中的作用域链和闭包
Apr 25 Javascript
详解如何提高 webpack 构建 Vue 项目的速度
Jul 03 Javascript
JavaScript无操作后屏保功能的实现方法
Jul 04 Javascript
javascript数据类型中的一些小知识点(推荐)
Apr 18 Javascript
vue和iview实现Scroll 数据无限滚动功能
Oct 31 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
文件上传类
2006/10/09 PHP
PHP 中的面向对象编程:通向大型 PHP 工程的办法
2006/12/03 PHP
php学习笔记(三)操作符与控制结构
2011/08/06 PHP
PHP中静态变量的使用方法实例分析
2016/12/01 PHP
PHPMailer使用QQ邮箱实现邮件发送功能
2017/08/18 PHP
PHP封装的XML简单操作类完整实例
2017/11/13 PHP
Yii2.0框架实现带分页的多条件搜索功能示例
2019/02/20 PHP
弹出广告特效(一个IP只弹出一次)的代码
2007/07/27 Javascript
A标签中通过href和onclick传递的this对象实现思路
2013/04/19 Javascript
解决JavaScript数字精度丢失问题的方法
2015/12/03 Javascript
全面了解JavaScirpt 的垃圾(garbage collection)回收机制
2016/07/11 Javascript
深入浅析JS是按值传递还是按引用传递(推荐)
2016/09/18 Javascript
JavaScript函数表达式详解及实例
2017/05/05 Javascript
五分钟搞懂Vuex实用知识(小结)
2019/08/12 Javascript
vue router动态路由设置参数可选问题
2019/08/21 Javascript
VUE+node(express)实现前后端分离
2019/10/13 Javascript
vue 使用外部JS与调用原生API操作示例
2019/12/02 Javascript
[01:32]2014DOTA2西雅图邀请赛 CIS我们有信心进入正赛
2014/07/08 DOTA
[02:30]联想杯DOTA2完美世界全国高校联赛—北京站现场
2015/11/16 DOTA
python开发之函数定义实例分析
2015/11/12 Python
python中redis的安装和使用
2016/12/04 Python
python实现简单点对点(p2p)聊天
2017/09/13 Python
Python2.X/Python3.X中urllib库区别讲解
2017/12/19 Python
Python中字符串与编码示例代码
2019/05/20 Python
python os.path.isfile 的使用误区详解
2019/11/29 Python
利用CSS3实现圆角的outline效果的教程
2015/06/05 HTML / CSS
用css3实现转换过渡和动画效果
2020/03/13 HTML / CSS
梵蒂冈和罗马卡:Omnia Card Pass
2018/02/10 全球购物
施工资料员岗位职责
2014/01/06 职场文书
《一个中国孩子的呼声》教学反思
2014/02/12 职场文书
党支部对照检查材料
2014/08/25 职场文书
个人买房协议书范本
2014/10/06 职场文书
党支部综合考察意见
2015/06/01 职场文书
2019客服个人年终工作总结范文
2019/07/08 职场文书
Canvas跟随鼠标炫彩小球的实现
2021/04/11 Javascript
Python办公自动化之教你用Python批量识别发票并录入到Excel表格中
2021/06/26 Python