需求:有一个数组,根据数组的值渲染对应的数字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 循环中函数变量暂存问题的更多相关文章

  1. JS循环中使用bind函数的参数传递问题

    JS循环中使用bind函数的参数传递问题,问题代码如下: for (var sc in result) { var tempp = '<div class="sidebar_todo_ ...

  2. Oracle中使用Table()函数解决For循环中不写成 in (l_idlist)形式的问题

    转: Oracle中使用Table()函数解决For循环中不写成 in (l_idlist)形式的问题 在实际PL/SQL编程中,我们要对动态取出来的一组数据,进行For循环处理,其基本程序逻辑为: ...

  3. js for 循环中的 变量问题。

    今日处理项目中的一个循环,本来就是一个小小的for循环,后来发现该段程序出现了问题,仔细检查代码没有发现其中的错误.无奈只好叫来了老大帮忙.通过在模版中断点调试(该方式只能自己写debugger断点) ...

  4. 百度地图API详解之事件机制,function“闭包”解决for循环和监听器冲突的问题:

    原文:百度地图API详解之事件机制,function"闭包"解决for循环和监听器冲突的问题: 百度地图API详解之事件机制 2011年07月26日 星期二 下午 04:06 和D ...

  5. 输出JS代码中的变量内容

    一. 输出JS代码中的变量内容 1. 可以直接以提示框的形式输出 alert("输出的内容"); 2. 可以输出到网页的某个位置 a. 在显示输出的位置放一个标签 <a id ...

  6. Handlebars.js循环中索引(@index)使用技巧(访问父级索引)

    使用Handlebars.js过程中,难免会使用循环,比如构造数据表格.而使用循环,又经常会用到索引,也就是获取当前循环到第几次了,一般会以这个为序号显示在页面上. Handlebars.js中获取循 ...

  7. 使用javax.script包实现Java设置JS脚本中的变量

    下面例子中,我们通过javax.script包ScriptEngine.put()方法设置JS脚本中的变量,JS把所有在线用户输出. package ajava.code.javase; import ...

  8. 【SQL】小心在循环中声明变量——浅析SQL变量作用域

    本文适用:T-SQL(SQL Server) 先看这个语句: --跑3圈 BEGIN --每圈都定义一个表变量,并插入一行 DECLARE @t TABLE(Col INT PRIMARY KEY) ...

  9. 彻底弄懂js循环中的闭包问题

    来源:http://www.108js.com/article/article1/10177.html?id=899 第一次接触这个问题还是在我刚开始学js的时候,当时就是一头雾水,时隔一年多了,突然 ...

随机推荐

  1. BurpSuite从下载安装到配置使用

    为解决一个XSS安全问题,第一次使用BurpSuite,记录一下下载安装到配置使用的过程,希望能对第一次使用该工具的朋友有所帮助. 一.下载及安装 直接百度下载破解版,我下的版本是burpsuite_ ...

  2. VS2012生成Web时报未能找到元数据文件xxx.dll

    问题:引用里已经添加了,还是报‘未能找到元数据文件xxx.dll’ 解决:添加了相同的不同路径的xxx.dll文件,删掉一个用不到的,就不报错了

  3. rm 删除文件太多

    在工程环境下,一个文件夹包含有100多万个文件,这时用命令去删除这些文件: rm -rf * 会出现报错如下: /bin/rm: cannot execute [Argument list too l ...

  4. MySql-第七篇单表查询

    1.MySQL中可以使用+.-.*./. 1>但MySQL中没有提供字符串连接运算符,可以使用concat(a_str,'xxx')进行连接. 2>在算术表达式中使用null,将会导致整个 ...

  5. [LOJ3123] CTSC2019重复

    Description 给定一个⻓为 n 的字符串 s , 问有多少个⻓为 m 的字符串 t 满足: 将 t 无限重复后,可以从中截出一个⻓度为 n 且字典序比 s 小的串. m ≤ 2000 n ≤ ...

  6. 【Python】Python实现Excel用例直接导入testlink-UI界面小工具

    1.写在前面 testlink上传用例一种方法是excel转换为xml,然后再用xml上传,还有一种是调用api进行上传.最开始写了个转换工具,是将excel转换为xml,然后在testlink里上传 ...

  7. 微信支付公众号支付redirect_uri域名与后台配置不一致,错误码10003

    最近弄微信支付,微信支付公众号支付redirect_uri域名与后台配置不一致,错误码10003,最容易出错两个地方 1,appid 对应不到 2,开发者网页授权 填写域名 文章来自http://ww ...

  8. 【接口工具】接口抓包工具之Charles

    上篇我们讲了Fiddler,Fiddler是用C#开发的,所以Fiddler不能在Mac系统中运行,没办法直接用Fiddler来截获MAC系统中的HTTP/HTTPS, Mac 用户怎么办呢? 1.F ...

  9. 67.Task Scheduler(任务规划)

    Level: Medium 题目描述: Given a char array representing tasks CPU need to do. It contains capital letter ...

  10. 为什么MySQL索引要使用 B+树,而不是其它树形结构?

    作者:李平 https://www.cnblogs.com/leefreeman/p/8315844.html 一个问题? InnoDB一棵B+树可以存放多少行数据?这个问题的简单回答是:约2千万 为 ...