我们在写web页面时,肯定会经常遇到下面这种情况:

<body>

<div class="btns-wrapper"></div>

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
var wrapper = $('.btns-wrapper');
for(var i = 0; i < 5; i++){
var btn = $('<button>按钮' + i + '</button>').appendTo(wrapper);
btn.on('click', function(evt){
console.log('点击按钮:' + i);
});
}
</script> </body>

代码很简单,就是在页面上创建几个按钮,同时定义按钮的点击事件

可当点击按钮时,我们发现获取到的序号一直都是5,也就是 i 最后的值。

这是因为定义click事件时的匿名函数所引用的都是同一个变量 i

解决办法1:立即执行

var wrapper = $('.btns-wrapper');
for(var i = 0; i < 5; i++){
var btn = $('<button>按钮' + i + '</button>').appendTo(wrapper); //默认方法
//btn.on('click', function(evt){
// console.log('点击按钮:' + i);
//}); //方法1:立即执行
btn.on('click', (function(n){
return function(evt){
console.log('点击按钮:' + n);
}
})(i)); }

这种方式就是在定义事件时直接为每个按钮都创建了一个独立的匿名函数(闭包),并且每个函数都持有正确的 i 变量

解决办法2:利用jquery的事件传参

var wrapper = $('.btns-wrapper');
for(var i = 0; i < 5; i++){
var btn = $('<button>按钮' + i + '</button>').appendTo(wrapper); //默认方法
//btn.on('click', function(evt){
// console.log('点击按钮:' + i);
//}); //方法2:利用JQuery的事件传参
btn.on('click', { i: i }, function(evt){
console.log('点击按钮:' + evt.data.i);
}); }

这种办法就简单多了,直接利用jquery将参数体传递给匿名函数即可。

解决办法3:利用dom的data属性

var wrapper = $('.btns-wrapper');
for(var i = 0; i < 5; i++){
var btn = $('<button>按钮' + i + '</button>').appendTo(wrapper); //默认方法
//btn.on('click', function(evt){
// console.log('点击按钮:' + i);
//}); //方法3:利用dom的data属性
btn.data('i', i);
btn.on('click', function(evt){
console.log('点击按钮:' + $(this).data('i'));
}); }

这种方法也很简单,弊端就是无法利用data属性定义结构化的数据。

综合来看,如果是jquery环境,利用事件参数来转递变量是最简单的,而且可以传递结构化的数据。

否则只能通过立即执行(闭包)的方式。

JavaScript中子函数访问外部变量的方法的更多相关文章

  1. ios中block访问外部变量的一些注意点

    Block类型是一个C级别的语法和运行机制.它与标准的C函数类似,不同之处在于,它除了有可执行代码以外,它还包含了与堆.栈内存绑定的变量.因此,Block对象包含着一组状态数据,这些数据在程序执行时用 ...

  2. javascript中函数声明、变量声明以及变量赋值之间的关系与影响

    javascript中函数声明.变量声明以及变量赋值之间的关系与影响 函数声明.变量声明以及变量赋值之间有以下几点共识: 1.所有的全局变量都是window的属性 2.函数声明被提升到范围作用域的顶端 ...

  3. Java 访问限制符 在同一包中或在不同包中:使用类创建对象的权限 & 对象访问成员变量与方法的权限 & 继承的权限 & 深入理解protected权限

    一.实例成员与类成员 1. 当类的字节码被加载到内存, 类中类变量.类方法即被分配了相应内存空间.入口地址(所有对象共享). 2. 当该类创建对象后,类中实例变量被分配内存(不同对象的实例变量互不相同 ...

  4. awk内置函数、外部变量

    外部变量 ①获取外部变量 格式: awk '{action}' 变量名=变量值 ,这样传入变量可以在action中获得值. 示例: test='awk test'--day-5 外部变量 ①获取外部变 ...

  5. PHP自定义函数使用外部变量

    一般,php的自定义函数不能直接使用外部变量. 在php自定义函数中使用外部变量前,需要先使用global对外部变量进行声明.  <?php $var = "hello World!& ...

  6. 关于Lambda表达式访问外部变量

    在<C#高级编程>一书中提到通过Lambda表达式可以访问Lambda表达式块外部的变量 ,这是一个很好的功能(类似Js中的 闭包).但是如果没有正确的使用,会非常危险. 比如下面的事例中 ...

  7. Javascript中函数提升和变量提升

    词法分析 词法分析方法: js运行前有一个类似编译的过程即词法分析,词法分析主要有三个步骤: 分析参数 再分析变量的声明 分析函数说明 具体步骤如下: 函数在运行的瞬间,生成一个活动对象(Active ...

  8. unittest之跳过用例(skip) (含如何调用类里面函数相互调取变量的方法)

    当测试用例写完后,有些模块有改动时候,会影响到部分用例的执行,这个时候我们希望暂时跳过这些用例. 或者前面某个功能运行失败了,后面的几个用例是依赖于这个功能的用例,如果第一步就失败了,后面的用例也就没 ...

  9. mybatis:访问静态变量或方法

    访问方法: <if test="@com.csget.constant.ConstantApp@getUser('mobile')== 'kf'"> <![CDA ...

随机推荐

  1. Redis6.x学习笔记(一)

    前言 最近学习Redis6.x,特做笔记以备忘,与大家共学.课程是从私塾在线下载的,他们把架构师课程都放出来了,大家可以去下载学习,不要钱的,地址是http://t.hk.uy/eac,课程很不错,值 ...

  2. 解读vue-server-renderer源码并在react中的实现

    前言 ​ 在博客开发的过程中,有这样一个需求想解决,就是在SSR开发环境中,服务端的代码是是直接通过webpack打包成文件(因为里面包含同构的代码,就是服务端与客户端共享前端的组件代码),写到磁盘里 ...

  3. 二分查找确定lower_bound和upper_bound

    lower_bound当target存在时, 返回它出现的第一个位置,如果不存在,则返回这样一个下标i:在此处插入target后,序列仍然有序. 代码如下: int lower_bound(int* ...

  4. 【转载】在Linux系统下用dd命令制作ISO镜像U盘启动盘

    #### 将U盘插入USB接口 #umount /dev/sdb* #dd if=/iso存放路径/XXX.iso of=/dev/sdb bs=1M ##### [转载]在Linux系统下用dd命令 ...

  5. Mysql数据库-多实例主从复制-主从故障详解

    一.mysql结构 1.实例 1.什么是单实例 一个进程 + 多个线程 + 一个预分配的内存空间 2.多实例 多个进程 + 多个线程 + 多个预分配的内存空间 ](http://shelldon.51 ...

  6. 010.kubernets的调度系统之daemonset

    daemonset简单操作使用 Deployment 是 Kubernetes 中用于处理无状态服务的资源,而 StatefulSet 是用于支持有状态服务的资源,这两种不同的资源从状态的角度对服务进 ...

  7. 7.7-9 chage、chpasswd、su

    7.7 chage:修改用户密码有效期 chage命令用于查看或修改用户密码的有效期,有些参数和passwd的功能相同.   -d    设置上一次密码更改的日期 -E    账号过期的日期.日期格式 ...

  8. Centos7 网卡DHCP重新获取IP地址

    问题:局域网内一台linux系统(Centos7.4)DHCP自动获取的IP地址和另一台手动配置的静态IP冲突了 解决方法:让DHCP自动获取的IP地址重新获取一个别的IP地址 DHCP重新获取IP ...

  9. GO学习-(24) Go语言操作Redis

    Go语言操作Redis 在项目开发中redis的使用也比较频繁,本文介绍了Go语言中go-redis库的基本使用. Redis介绍 Redis是一个开源的内存数据库,Redis提供了多种不同类型的数据 ...

  10. Docker学习(10) Docker的远程访问

    Docker的远程访问 只需配置