用闭包解决 js 循环中函数变量暂存问题
需求:有一个数组,根据数组的值渲染对应的数字div,单击对应的div 在控制台打印对应的数字。如点击1,控制台打印1.
问题: 不管点击哪个值 打出来都是4
代码如下
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>testFor</title>
</head>
<body>
<div id="container">
</div>
<script>
var arr=[1,2,3,4];
function clickNum(i) {
console.log(i)
}
for(var i of arr){
var iDiv=document.createElement('div');
iDiv.addEventListener('click',function () {
clickNum(i)
});
iDiv.innerText=i;
var container=document.getElementById('container');
container.appendChild(iDiv);
}
</script>
</body>
</html>
期望点击会打印出对应的数字,实际打出来的都是4
原因:
js函数在声明时,浏览器不会去查看函数内部逻辑。只有函数被使用时 才关心函数内部的变量引用。
如本例,只有在单击的时候 才会去触发clickNum函数,而此时循环已执行完毕,i已经变成了4。 所以不管哪个div的click 事件打印出来永远都是4。
解决思路:
1.因为我们需要用到即时的索引值i.所以 我们需要立即触发此函数。这里需要用到匿名函数。
2.有了匿名函数立即执行后,我们还需要将匿名函数中的变量暂存起来,留着点击的时候用,这里需要创建一个闭包。因为闭包的本质就是让内部的变量在函数执行完后也不被垃圾回收调。而是暂存起来。所以,如果需要在函数外部拿到函数内部的变量。或者想在将来拿到现在的变量 都只能通过闭包(我个人理解是这样的)
改后的代码
for(var i of arr){
var iDiv=document.createElement('div');
iDiv.addEventListener('click',function (icopy) {
return function () {
clickNum(icopy)
}
}(i));
iDiv.innerText=i;
var container=document.getElementById('container');
container.appendChild(iDiv);
}
用闭包解决 js 循环中函数变量暂存问题的更多相关文章
- JS循环中使用bind函数的参数传递问题
JS循环中使用bind函数的参数传递问题,问题代码如下: for (var sc in result) { var tempp = '<div class="sidebar_todo_ ...
- Oracle中使用Table()函数解决For循环中不写成 in (l_idlist)形式的问题
转: Oracle中使用Table()函数解决For循环中不写成 in (l_idlist)形式的问题 在实际PL/SQL编程中,我们要对动态取出来的一组数据,进行For循环处理,其基本程序逻辑为: ...
- js for 循环中的 变量问题。
今日处理项目中的一个循环,本来就是一个小小的for循环,后来发现该段程序出现了问题,仔细检查代码没有发现其中的错误.无奈只好叫来了老大帮忙.通过在模版中断点调试(该方式只能自己写debugger断点) ...
- 百度地图API详解之事件机制,function“闭包”解决for循环和监听器冲突的问题:
原文:百度地图API详解之事件机制,function"闭包"解决for循环和监听器冲突的问题: 百度地图API详解之事件机制 2011年07月26日 星期二 下午 04:06 和D ...
- 输出JS代码中的变量内容
一. 输出JS代码中的变量内容 1. 可以直接以提示框的形式输出 alert("输出的内容"); 2. 可以输出到网页的某个位置 a. 在显示输出的位置放一个标签 <a id ...
- Handlebars.js循环中索引(@index)使用技巧(访问父级索引)
使用Handlebars.js过程中,难免会使用循环,比如构造数据表格.而使用循环,又经常会用到索引,也就是获取当前循环到第几次了,一般会以这个为序号显示在页面上. Handlebars.js中获取循 ...
- 使用javax.script包实现Java设置JS脚本中的变量
下面例子中,我们通过javax.script包ScriptEngine.put()方法设置JS脚本中的变量,JS把所有在线用户输出. package ajava.code.javase; import ...
- 【SQL】小心在循环中声明变量——浅析SQL变量作用域
本文适用:T-SQL(SQL Server) 先看这个语句: --跑3圈 BEGIN --每圈都定义一个表变量,并插入一行 DECLARE @t TABLE(Col INT PRIMARY KEY) ...
- 彻底弄懂js循环中的闭包问题
来源:http://www.108js.com/article/article1/10177.html?id=899 第一次接触这个问题还是在我刚开始学js的时候,当时就是一头雾水,时隔一年多了,突然 ...
随机推荐
- 把任意的EXE嵌入到自己程序中
把任意的EXE嵌入到自己程序中 taoyuan19822008-08-24上传 Delphi把任意的EXE嵌入到自己程序中的程序 资源积分:0分 下载次数:327 资源类型:其他 资源大小:175 ...
- poj1163The Triangle(动态规划,记忆化搜索)
7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 (Figure 1) Figure 1 shows a number triangle. Write a program that calc ...
- 排序,其他的运用 os fork
while True: str_num = input("Enter number:") flag = True dotCount = 0 if str_num[0] == '-' ...
- flask为blueprint增加error_handler
对整个app增加errorhandler,只需如下: @portal_page.errorhandler(404) def page_not_found(error): cats = Category ...
- kmp(所有长度的前缀与后缀)
http://poj.org/problem?id=2752 Seek the Name, Seek the Fame Time Limit: 2000MS Memory Limit: 65536 ...
- 观list.clear()方法 有感
一 . list.clear()底层源码实现 在使用list 结合的时候习惯了 list=null :在创建这样的方式,但是发现使用list的clear 方法很不错,尤其是有大量循环的时候 1.lis ...
- C# lodop 打印控件的使用
原文:https://www.cnblogs.com/izhiniao/p/4160117.html 官网:http://www.mtsoftware.cn/demo.html 先看效果图 : lod ...
- 【JAVA】 05-String类和JDK5
链接: 笔记目录:毕向东Java基础视频教程-笔记 GitHub库:JavaBXD33 目录: <> <> 内容待整理: API-String 特点 String类: 1.St ...
- 搭建阿里云服务器(centos,jdk和Tomcat版本)
1.购买服务器(登录阿里云,购买服务器,并进入控制台,查看自己的服务器实例 2.域名注册(这步可以省略,直接IP地址访问,因为域名需要备案),购买域名的需要进行解析以及绑定自己的服务器 3.可以准备一 ...
- JS中的匿名函数、回调函数、匿名回调函数
工欲善其事必先利其器 在学习JavaScript设计模式一书时,遇到了“匿名回调函数”这个概念,有点疑惑,查找了些资料重新看了下函数的相关知识点之后,对这个概念有了认识.九层之台,起于垒土.在熟悉这一 ...