JavaScript中子函数访问外部变量的方法
我们在写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中子函数访问外部变量的方法的更多相关文章
- ios中block访问外部变量的一些注意点
Block类型是一个C级别的语法和运行机制.它与标准的C函数类似,不同之处在于,它除了有可执行代码以外,它还包含了与堆.栈内存绑定的变量.因此,Block对象包含着一组状态数据,这些数据在程序执行时用 ...
- javascript中函数声明、变量声明以及变量赋值之间的关系与影响
javascript中函数声明.变量声明以及变量赋值之间的关系与影响 函数声明.变量声明以及变量赋值之间有以下几点共识: 1.所有的全局变量都是window的属性 2.函数声明被提升到范围作用域的顶端 ...
- Java 访问限制符 在同一包中或在不同包中:使用类创建对象的权限 & 对象访问成员变量与方法的权限 & 继承的权限 & 深入理解protected权限
一.实例成员与类成员 1. 当类的字节码被加载到内存, 类中类变量.类方法即被分配了相应内存空间.入口地址(所有对象共享). 2. 当该类创建对象后,类中实例变量被分配内存(不同对象的实例变量互不相同 ...
- awk内置函数、外部变量
外部变量 ①获取外部变量 格式: awk '{action}' 变量名=变量值 ,这样传入变量可以在action中获得值. 示例: test='awk test'--day-5 外部变量 ①获取外部变 ...
- PHP自定义函数使用外部变量
一般,php的自定义函数不能直接使用外部变量. 在php自定义函数中使用外部变量前,需要先使用global对外部变量进行声明. <?php $var = "hello World!& ...
- 关于Lambda表达式访问外部变量
在<C#高级编程>一书中提到通过Lambda表达式可以访问Lambda表达式块外部的变量 ,这是一个很好的功能(类似Js中的 闭包).但是如果没有正确的使用,会非常危险. 比如下面的事例中 ...
- Javascript中函数提升和变量提升
词法分析 词法分析方法: js运行前有一个类似编译的过程即词法分析,词法分析主要有三个步骤: 分析参数 再分析变量的声明 分析函数说明 具体步骤如下: 函数在运行的瞬间,生成一个活动对象(Active ...
- unittest之跳过用例(skip) (含如何调用类里面函数相互调取变量的方法)
当测试用例写完后,有些模块有改动时候,会影响到部分用例的执行,这个时候我们希望暂时跳过这些用例. 或者前面某个功能运行失败了,后面的几个用例是依赖于这个功能的用例,如果第一步就失败了,后面的用例也就没 ...
- mybatis:访问静态变量或方法
访问方法: <if test="@com.csget.constant.ConstantApp@getUser('mobile')== 'kf'"> <![CDA ...
随机推荐
- PE文件中的输入表
前言 PE文件中的输入表含有三个重要结构IID,IDT,IAT.PE文件为需要加载的DLL文件创建一个IID结构,一个DLL与一个IID对应.IDT是输入名称表,IAT输入地址表,在没有绑定输入的情况 ...
- 更新索引库: $locate string 寻找包含有string的路径: $updatedb
更新索引库: $locate string 寻找包含有string的路径: $updatedb 与find不同,locate并不是实时查找.你需要更新数据库,以获得最新的文件索引信息.
- bug修复
bug严重级别 bug个数 bug修复率 上个版本的bug修复率 和arm对比 arm已修复
- Sqli-labs-master通关解析(持续更新中。。。)
大多情况下:SQL注入其实就是构造正确的mysql命令,让网页回显本不应该让我们看到的数据(如用户的账号和密码). 第一关-联合查询注入 查库 // 查看当前页面在的数据库 ?id=-1' union ...
- http协议工作原理及工作流程
什么是url ? url = 协议 + 域名 + 资源路径 比如: https://www.baidu.com/index.html http : 超文本传输协议 https: 安全套接字协议 HTT ...
- Centos 7.4搭建es7.12.0+Skywalking7.8.5
Skywalking整体架构图和分布式追踪系统原理:https://blog.csdn.net/weixin_39866487/article/details/111581322 软件包版本1.ela ...
- JQuery 动态加载 HTML 元素时绑定点击事件无效问题
问题描述 假设项目中有一个列表页面,如下: 当点击列表一行数据可以显示详情页面,而详情页面的数据是根据当前行的数据作为参数,通过 ajax 请求到后台返回的数据,再根据返回的结果动态生成 html 页 ...
- JRebel插件使用详解(IDEA热部署)(Day_44)
JRebel插件使用详解 简介 JRebel是一套JavaEE开发工具. Jrebel 可快速实现热部署,节省了大量重启时间,提高了个人开发效率. JRebel是一款JAVA虚拟机插件,它使得JAVA ...
- fragment之间相互传数据、共享数据
在 Fragment 之间共享数据 Activity 中的两个或更多 Fragment 需要相互通信是一种很常见的现象.想象一下拆分视图 (master-detail) Fragment 的常见情况, ...
- conda 按照指定源下载python包
conda 按照指定源下载python包 换成了国内的pip源就可以正常安装了,我使用的是:pip install xlrd -i http://pypi.douban.com/simple --tr ...