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 相关文章推荐
jQuery autocomplete插件修改
Apr 17 Javascript
JavaScript DOM 编程艺术(第2版)读书笔记(JavaScript的最佳实践)
Oct 01 Javascript
JS冒泡事件的快速解决方法
Dec 16 Javascript
js实现键盘Enter键提交表单的方法
May 27 Javascript
JQuery zClip插件实现复制页面内容到剪贴板
Nov 02 Javascript
跟我学习javascript的浮点数精度
Nov 16 Javascript
AngularJS用户选择器指令实例分析
Nov 04 Javascript
JavaScript实现form表单的多文件上传
Mar 27 Javascript
jQuery实现checkbox即点即改批量删除及中间遇到的坑
Nov 11 jQuery
JavaScript遍历DOM元素的常见方式示例
Feb 16 Javascript
将RGB值转换为灰度值的简单算法
Oct 09 Javascript
Vue组件间的通信pubsub-js实现步骤解析
Mar 11 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脚本执行卡住的问题
2016/12/27 PHP
PHP排序二叉树基本功能实现方法示例
2018/05/26 PHP
PHP mongodb操作类定义与用法示例【适合mongodb2.x和mongodb3.x】
2018/06/16 PHP
PHP添加PNG图片背景透明水印操作类定义与用法示例
2019/03/12 PHP
prototype 中文参数乱码解决方案
2009/11/09 Javascript
jquery获取焦点和失去焦点事件代码
2013/04/21 Javascript
NodeJS Express框架中处理404页面一个方式
2014/05/28 NodeJs
Vue结合原生js实现自定义组件自动生成示例
2017/01/21 Javascript
jQuery+CSS3实现点赞功能
2017/03/13 Javascript
JavaScript中使用webuploader实现上传视频功能(demo)
2017/04/10 Javascript
AngularJS双向绑定和依赖反转实例详解
2017/04/15 Javascript
基于three.js编写的一个项目类示例代码
2018/01/05 Javascript
JQuery判断radio单选框是否选中并获取值的方法
2019/01/17 jQuery
使用express来代理服务的方法
2019/06/21 Javascript
[00:55]深扒TI7聊天轮盘语音出处3
2017/05/11 DOTA
Python内建数据结构详解
2016/02/03 Python
Python实现的简单模板引擎功能示例
2017/09/02 Python
基于python中的TCP及UDP(详解)
2017/11/06 Python
用Python写脚本,实现完全备份和增量备份的示例
2018/04/29 Python
一行代码让 Python 的运行速度提高100倍
2018/10/08 Python
Python3实现爬虫爬取赶集网列表功能【基于request和BeautifulSoup模块】
2018/12/05 Python
Windows下python3安装tkinter的问题及解决方法
2020/01/06 Python
Python类如何定义私有变量
2020/02/03 Python
用ldap作为django后端用户登录验证的实现
2020/12/07 Python
如何利用python正则表达式匹配版本信息
2020/12/09 Python
canvas环形倒计时组件的示例代码
2018/06/14 HTML / CSS
异步传递消息系统的作用
2016/05/01 面试题
校园报刊亭创业计划书
2014/01/02 职场文书
人事部岗位职责范本
2014/03/05 职场文书
员工工作表现评语
2014/04/26 职场文书
大班亲子运动会方案
2014/06/10 职场文书
群众路线四风自我剖析材料
2014/10/08 职场文书
2014年高二班主任工作总结
2014/12/16 职场文书
原告离婚代理词
2015/05/23 职场文书
房屋产权证明书
2015/06/19 职场文书
深入解析NumPy中的Broadcasting广播机制
2021/05/30 Python