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 实现父窗口引用弹出窗口的值的脚本
Aug 07 Javascript
JavaScript使用技巧精萃[代码非常实用]
Nov 21 Javascript
同一页面多个商品倒计时JS 基于面向对象的javascript
Feb 16 Javascript
javascript学习笔记(一)基础知识
Sep 30 Javascript
详解原生JavaScript实现jQuery中AJAX处理的方法
May 10 Javascript
JS树形菜单组件Bootstrap TreeView使用方法详解
Dec 21 Javascript
jquery 禁止鼠标右键并监听右键事件
Apr 27 jQuery
在Vue中使用echarts的实例代码(3种图)
Jul 10 Javascript
Vue动态生成el-checkbox点击无法赋值的解决方法
Feb 21 Javascript
node实现爬虫的几种简易方式
Aug 22 Javascript
Vue解析带html标签的字符串为dom的实例
Nov 13 Javascript
Node.js 深度调试方法解析
Jul 28 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
隐藏X-Space个人空间下方版权方法隐藏X-Space个人空间标题隐藏X-Space个人空间管理版权方法
2007/02/22 PHP
编写PHP程序检查字符串中的中文字符个数的实例分享
2016/03/17 PHP
php计数排序算法的实现代码(附四个实例代码)
2020/03/31 PHP
用js实现计算代码行数的简单方法附代码
2007/08/13 Javascript
JS 实现导航栏悬停效果
2013/09/23 Javascript
js实现鼠标经过时图片滚动停止的方法
2015/02/16 Javascript
jQuery animate和CSS3相结合实现缓动追逐效果附源码下载
2016/04/18 Javascript
javascript按顺序加载运行js方法
2017/12/01 Javascript
vue将对象新增的属性添加到检测序列的方法
2018/02/24 Javascript
微信小程序全局变量功能与用法详解
2019/01/22 Javascript
微信小程序自定义弹出层效果
2020/05/26 Javascript
原生js滑动轮播封装
2020/07/31 Javascript
[05:45]Ti4观战指南(下)
2014/07/07 DOTA
python正则表达式中的括号匹配问题
2014/12/14 Python
把项目从Python2.x移植到Python3.x的经验总结
2015/04/20 Python
python版大富翁源代码分享
2018/11/19 Python
Python设计模式之职责链模式原理与用法实例分析
2019/01/11 Python
在Python中使用Neo4j的方法
2019/03/14 Python
Python selenium的基本使用方法分析
2019/12/21 Python
python 安装impala包步骤
2020/03/28 Python
基于PyInstaller各参数的含义说明
2021/03/04 Python
使用CSS3设计地图上的雷达定位提示效果
2016/04/05 HTML / CSS
Photobook澳大利亚:制作相片书,婚礼卡,旅行相簿
2017/01/12 全球购物
FitFlop澳大利亚官网:英国符合人体工学的鞋类品牌
2017/06/05 全球购物
某公司C#程序员面试题笔试题
2014/05/26 面试题
艺术设计专业个人求职信范文
2013/12/11 职场文书
犯错检讨书
2014/02/21 职场文书
优秀的2014年两会精神解读
2014/03/17 职场文书
药剂专业毕业生求职信
2014/06/24 职场文书
2015感人爱情寄语
2015/02/26 职场文书
酒店总经理岗位职责
2015/04/01 职场文书
2015年电话销售工作总结范文
2015/04/20 职场文书
2016保送生自荐信范文
2016/01/29 职场文书
优秀新员工事迹材料
2019/05/13 职场文书
Python开发工具Pycharm的安装以及使用步骤总结
2021/06/24 Python
Redis实现短信验证码登录的示例代码
2022/06/14 Redis