需求:有一个数组,根据数组的值渲染对应的数字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. Vagrant 手册之 Vagrantfile - 配置版本

    原文地址 配置版本是 Vagrant 1.1+(引入了大量新功能和配置选项) 能够与 Vagrant 1.0.x Vagrantfiles 保持向后兼容的机制. 现在运行 vagrant init 时 ...

  2. Django+python报错与解决方法

    编码信息导致修改django文件下的debug.py文件331行的编码格式 with Path(CURRENT_DIR, 'templates', 'technical_500.html').open ...

  3. 深信达加密下禁用IME

    1.控制面板 2.管理工具 3.计算机管理 4.系统工具 5.任务计划程序 6.任务计划程序库 7.Microsoft 8.Windows 9.TextServicesFramework 10.MsC ...

  4. redis可以做什么?

    redis可以做什么? 1.缓存,毫无疑问这是Redis当今最为人熟知的使用场景.在提升服务器性能方面非常有效: 2.排行榜,如果使用传统的关系型数据库来做这个事儿,非常的麻烦,而利用Redis的So ...

  5. LayUI Table复杂表头实现

    LayUI table官方文档中在介绍复杂表头时的用例仅使用了自动渲染的方式作为参考,而并未用到方法渲染的方式来做用例,这让部分不太熟悉layUI table的开发者会有些头疼,不知道如何在方法渲染中 ...

  6. 用Emacs编写mybatis

    用Emacs编写mybatis */--> code {color: #FF0000} pre.src {background-color: #002b36; color: #839496;} ...

  7. How Many Answers Are Wrong (HDU - 3038)(带权并查集)

    题目链接 并查集是用来对集合合并查询的一种数据结构,或者判断是不是一个集合,本题是给你一系列区间和,判断给出的区间中有几个是不合法的. 思考: 1.如何建立区间之间的联系 2.如何发现悖论 首先是如何 ...

  8. rsync配置教程

    本文默认服务器已经安装了 rsync ! 本文默认服务器已经安装了 rsync ! 本文默认服务器已经安装了 rsync ! 切换到 /etc目录,默认情况下,rsyncd.conf 文件如下: # ...

  9. StatusStrip 分类: C# 2015-07-23 11:58 2人阅读 评论(0) 收藏

    通过StatusStrip显示窗体状态栏 同时将状态栏分成三部分 居左边显示相关文字信息 中间空白显示 居右边显示时间信息 1.创建窗体及添加StatusStrip   默认StatusStrip名称 ...

  10. C#设计模式:建造者模式(Builder Pattern)

    一,建造者模式(Builder Pattern) using System; using System.Collections.Generic; using System.Linq; using Sy ...