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中的对象和数组的应用技巧
Jan 07 Javascript
jQuery获取注册信息并提示实现代码
Apr 21 Javascript
深入理解JavaScript是如何实现继承的
Dec 12 Javascript
模拟用户点击弹出新页面不会被浏览器拦截
Apr 08 Javascript
JS中的THIS和WINDOW.EVENT.SRCELEMENT详解
May 25 Javascript
webstorm和.vue中es6语法报错的解决方法
May 08 Javascript
Node.js Buffer用法解读
May 18 Javascript
Babel 入门教程学习笔记
Jun 13 Javascript
详解微信小程序调起键盘性能优化
Jul 24 Javascript
vue router 跳转时打开新页面的示例方法
Jul 28 Javascript
通过js随机函数Math.random实现乱序
May 19 Javascript
ReactRouter的实现方法
Jan 25 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跨站刷票的实现代码
2013/06/18 PHP
PHP中file_exists函数不支持中文名的解决方法
2014/07/26 PHP
php中执行系统命令的方法
2015/03/21 PHP
Yii2组件之多图上传插件FileInput的详细使用教程
2016/06/20 PHP
Laravel框架实现定时发布任务的方法
2018/08/16 PHP
优化innerHTML操作(提高代码执行效率)
2011/08/20 Javascript
javascript表单验证 - Parsley.js使用和配置
2013/01/25 Javascript
javascript获取元素CSS样式代码示例
2013/11/28 Javascript
js实现的类似于asp数据字典的数据类型代码实例
2014/09/03 Javascript
jQuery动态创建html元素的常用方法汇总
2014/09/05 Javascript
Javascript学习指南
2014/12/01 Javascript
js查找节点的方法小结
2015/01/13 Javascript
JavaScript中的包装对象介绍
2015/01/27 Javascript
简单谈谈Javascript中类型的判断
2015/10/19 Javascript
JavaScript事件类型中UI事件详解
2016/01/14 Javascript
轻松搞定js表单验证
2016/10/13 Javascript
微信小程序组件 contact-button(客服会话按钮)详解及实例代码
2017/01/10 Javascript
laravel5.4+vue+element简单搭建的示例代码
2017/08/29 Javascript
基于ES6 Array.of的用法(实例讲解)
2017/09/05 Javascript
IntelliJ IDEA 安装vue开发插件的方法
2017/11/21 Javascript
angular.js和vue.js中实现函数去抖示例(debounce)
2018/01/18 Javascript
微信小程序实现多选删除列表数据功能示例
2019/01/15 Javascript
Python 通配符删除文件的实例
2018/04/24 Python
Python使用folium excel绘制point
2019/01/03 Python
python中pygame安装过程(超级详细)
2019/08/04 Python
python numpy存取文件的方式
2020/04/01 Python
什么是触发器(trigger)? 触发器有什么作用?
2013/09/18 面试题
sealed修饰符是干什么的
2012/10/23 面试题
测绘工程本科生求职信
2013/10/10 职场文书
《猴子种树》教学反思
2014/02/14 职场文书
优秀班组申报材料
2014/12/25 职场文书
紧急通知
2015/04/17 职场文书
校长新学期寄语2016
2015/12/04 职场文书
导游词之徐州-云龙山
2019/09/29 职场文书
使用Python脚本对GiteePages进行一键部署的使用说明
2021/05/27 Python
Pillow图像处理库安装及使用
2022/04/12 Python