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 相关文章推荐
js 鼠标点击事件及其它捕获
Jun 04 Javascript
向大师们学习Javascript(视频与PPT)
Dec 27 Javascript
js遍历td tr等html元素
Dec 13 Javascript
JavaScript中使用Math.floor()方法对数字取整
Jun 15 Javascript
JS图片等比例缩放方法完整示例
Aug 03 Javascript
微信小程序 wx:key详细介绍
Oct 28 Javascript
利用types增强vscode中js代码提示功能详解
Jul 07 Javascript
详解如何在vue项目中引入elementUI组件
Feb 11 Javascript
Bootbox将后台JSON数据填充Form表单的实例代码
Sep 10 Javascript
vue引入微信sdk 实现分享朋友圈获取地理位置功能
Jul 04 Javascript
Vue中keep-alive 实现后退不刷新并保持滚动位置
Mar 17 Javascript
vue实现点击按钮切换背景颜色的示例代码
Jun 23 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
深入file_get_contents函数抓取内容失败的原因分析
2013/06/25 PHP
Yii2使用小技巧之通过 Composer 添加 FontAwesome 字体资源
2014/06/22 PHP
php实现的一个简单json rpc框架实例
2015/03/30 PHP
简介PHP的Yii框架中缓存的一些高级用法
2016/03/29 PHP
JQuery AJAX提交中文乱码的解决方案
2010/07/02 Javascript
根据经纬度计算地球上两点之间的距离js实现代码
2013/03/05 Javascript
jquery调取json数据实现省市级联的方法
2015/01/29 Javascript
jquery实现对联广告的方法
2015/02/05 Javascript
对比分析AngularJS中的$http.post与jQuery.post的区别
2015/02/27 Javascript
省市联动效果的简单实现代码(推荐)
2016/06/06 Javascript
Bootstrap实现登录校验表单(带验证码)
2016/06/23 Javascript
详解Python中logging日志模块在多进程环境下的使用
2016/12/26 Javascript
微信小程序教程系列之设置标题栏和导航栏(7)
2020/06/29 Javascript
canvas+gif.js打造自己的数字雨头像的示例代码
2017/10/26 Javascript
浅析Vue自定义组件的v-model
2017/11/26 Javascript
node.js中路由,中间件,ge请求和post请求的参数详解
2017/12/26 Javascript
angular4 共享服务在多个组件中数据通信的示例
2018/03/30 Javascript
Javascript获取某个月的天数
2018/05/30 Javascript
vue移动端监听滚动条高度的实现方法
2018/09/03 Javascript
使用vue-cli webpack 快速搭建项目的代码
2018/11/21 Javascript
Python中的super()方法使用简介
2015/08/14 Python
实例讲解Python中SocketServer模块处理网络请求的用法
2016/06/28 Python
关于Python面向对象编程的知识点总结
2017/02/14 Python
Python-OpenCV基本操作方法详解
2018/04/02 Python
Python实现繁?转为简体的方法示例
2018/12/18 Python
python错误调试及单元文档测试过程解析
2019/12/19 Python
np.dot()函数的用法详解
2020/01/17 Python
python实现网页录音效果
2020/10/26 Python
追悼会子女答谢词
2014/01/28 职场文书
初三新学期计划书
2014/05/03 职场文书
中国梦口号
2014/06/13 职场文书
校园活动策划方案
2014/06/13 职场文书
汽车修理厂管理制度
2015/08/05 职场文书
2016见义勇为事迹材料汇总
2016/03/01 职场文书
Pytest实现setup和teardown的详细使用详解
2021/04/17 Python
JS异步堆栈追踪之为什么await胜过Promise
2021/04/28 Javascript