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 克隆数组最简单的方法
Feb 12 Javascript
javascript web页面刷新的方法收集
Jul 02 Javascript
JS控制阿拉伯数字转为中文大写示例代码
Sep 04 Javascript
JS判断变量是否为空判断是否null
Jul 25 Javascript
jquery ajax请求方式与提示用户正在处理请稍等
Sep 01 Javascript
JavaScript中使用Math.PI圆周率属性的方法
Jun 14 Javascript
深入理解jQuery3.0的domManip函数
Sep 01 Javascript
Javascript(es2016) import和require用法和区别详解
Aug 11 Javascript
Vue中父子组件通讯之todolist组件功能开发
May 21 Javascript
vue 项目打包通过命令修改 vue-router 模式 修改 API 接口前缀
Jun 13 Javascript
nuxt 实现在其它js文件中使用store的方式
Nov 05 Javascript
深入讲解Vue中父子组件通信与事件触发
Mar 22 Vue.js
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 mysql数据库操作类
2008/06/04 PHP
php中选择什么接口(mysql、mysqli)访问mysql
2013/02/06 PHP
Laravel 5框架学习之向视图传送数据
2015/04/08 PHP
PHP中的switch语句的用法实例详解
2015/10/21 PHP
PHP常见数组函数用法小结
2016/03/21 PHP
php-fpm开启状态统计的方法详解
2017/06/23 PHP
TP5框架实现的数据库备份功能示例
2020/04/05 PHP
游戏人文件夹程序 ver 4.03
2006/07/14 Javascript
JQuery 插件模板 制作jquery插件的朋友可以参考下
2010/03/17 Javascript
js URL参数的拼接方法比较
2012/02/15 Javascript
Jquery通过JSON字符串创建JSON对象
2014/08/24 Javascript
JavaScript中检查对象property的存在性方法介绍
2014/12/30 Javascript
JQuery基础语法小结
2015/02/27 Javascript
JS动态添加iframe的代码
2015/09/14 Javascript
JavaScript数据绑定实现一个简单的 MVVM 库
2016/04/08 Javascript
详解vue表单验证组件 v-verify-plugin
2017/04/19 Javascript
详解vue2.0脚手架的webpack 配置文件分析
2017/05/27 Javascript
搭建element-ui的Vue前端工程操作实例
2018/02/23 Javascript
vue-cli3环境变量与分环境打包的方法示例
2019/02/18 Javascript
小程序采集录音并上传到后台
2019/11/22 Javascript
JS原型和原型链原理与用法实例详解
2020/02/05 Javascript
js实现简单点赞操作
2020/03/17 Javascript
Vue3不支持Filters过滤器的问题
2020/09/24 Javascript
python单线程实现多个定时器示例
2014/03/30 Python
快速入手Python字符编码
2016/08/03 Python
python实现时间o(1)的最小栈的实例代码
2018/07/23 Python
快速解决vue.js 模板和jinja 模板冲突的问题
2019/07/26 Python
Cpython解释器中的GIL全局解释器锁
2020/11/09 Python
前端实现背景虚化但内容清晰且自适应 的实例代码
2019/08/01 HTML / CSS
购买瑞典当代设计的腕表和太阳眼镜:TRIWA
2016/10/30 全球购物
英国买鞋网站:Charles Clinkard
2019/11/14 全球购物
解释下列WebService名词:WSDL、SOAP、UDDI
2012/06/22 面试题
计算机专业职业生涯规划范文
2014/01/19 职场文书
初一学生期末评语
2014/04/24 职场文书
大学生党员自我批评思想汇报
2014/10/10 职场文书
限期整改通知书
2015/04/22 职场文书