需求:有一个数组,根据数组的值渲染对应的数字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. linux文件夹 权限为所有用户可 读写

    使用命令: sudo chmod dirname -R

  2. PHP安装-centos7

    下载地址:https://www.php.net/downloads.php 1.wget下载php源码至/usr/local/src 下 wget https://www.php.net/distr ...

  3. 设计模式 - 门面模式(Facade Pattern,也叫外观模式)

    简介 场景 将系统划分为若干个子系统有利于降低系统的复杂性,但是这会增加调用者的复杂性.通过引入 Facade 可以对调用者屏蔽系统内部子系统的细节. Java 中有多个日志库,例如 log4j.lo ...

  4. C# 中定义斜杠 \

    \ 是转义符 如     \’ 单引号    \” 双引号    \\ 反斜杠    \0 空    \a 警告(产生峰鸣)    \b 退格    \f 换页    \n 换行    \r 回车   ...

  5. Node.js实战5:操作系统与命令行。

    Nodejs有一些内置的方法可以查询操作系统信息: 如: process.arch获取到系统是32位还是64位, process.platform可获取系统的类型. 例程: console.log(p ...

  6. 如何学习 websocket ?

    如何学习 websocket ? 使用 HTML https://github.com/phoboslab/jsmpeg MPEG1 进行播放 https://w3c.github.io/media- ...

  7. c#catch循环内捕获到异常继续循环

    一,如果我们将异常而不影响循环,如下代码: using System; using System.Collections.Generic; using System.Linq; using Syste ...

  8. 2018-7-24-WPF-渲染级别

    title author date CreateTime categories WPF 渲染级别 lindexi 2018-07-24 18:46:27 +0800 2018-04-20 16:26: ...

  9. Centos上Docker的安装及加速

    #环境 :内核的版本必须大于3.10 #安装docker yum install epel-release -y yum install docker-ce ##安装docker-ce #配置文件 d ...

  10. Zabbix学习笔记(yum源安装)

    Zabbix学习笔记(yum源安装) 链接:https://pan.baidu.com/s/19RXhumkB-ulpI4BGOa5b_A 提取码:115h 复制这段内容后打开百度网盘手机App,操作 ...