考虑一下以下的代码片段:

for (var i = 0; i < 5; i++) {
var btn = document.createElement('button');
btn.appendChild(document.createTextNode('Button ' + i));
btn.addEventListener('click', function(){ console.log(i); });
document.body.appendChild(btn);
}

(a)当用户点击“Button4”的时候会打印什么?并解释为什么?

(b)提供一个或多个正确的实现方式。

答:(a)无论点击哪个按钮,都将打印5.因为任何按钮在调用onclick方法时,for循环已经完成了,变量i的值变成了5.

  (b)关键是要抓住在每一次循环for的时候要把i的值传人到最近创建的函数对象中。

下面有三个可能的方式解决这个问题:

//方法1:作为函数参数调用
for (var i = 0; i < 5; i++) {
var btn = document.createElement('button');
btn.appendChild(document.createTextNode('Button ' + i));
btn.addEventListener('click', (function(i) {
return function() { console.log(i); };
})(i));
document.body.appendChild(btn);
} //方法2:将整个btn.addEventListener封装在一个新的匿名函数里
for (var i = 0; i < 5; i++) {
var btn = document.createElement('button');
btn.appendChild(document.createTextNode('Button ' + i));
(function (i) {
btn.addEventListener('click', function() { console.log(i); });
})(i);
document.body.appendChild(btn);
} //方法3:将for循环换成array对象的本地调用方法forEach.
['a', 'b', 'c', 'd', 'e'].forEach(function (value, i) {
var btn = document.createElement('button');
btn.appendChild(document.createTextNode('Button ' + i));
btn.addEventListener('click', function() { console.log(i); });
document.body.appendChild(btn);
});

For循环和闭包问题的更多相关文章

  1. 说说循环与闭包——《你不知道的JS》读书笔记(一)

    什么是闭包 <你不知道的JS>里有对闭包的定义:"当函数可以记住并访问所在的词法作用域,即使函数是在当前作用域之外执行,这就产生了闭包." 讲闭包是啥的太多了...就一 ...

  2. JavaScript中的循环和闭包

    看一段比较经典的错误代码: // 希望获取页面上的所有div,在点击的时输出对应的编号 var oDom = document.querySelectorAll("div"); / ...

  3. golang 循环创建闭包 问题排查

    ][]string{ { { "邀请码是什么", "我没有邀请码", "这个邀请码我可以随便填吗", "邀请码可以填他的手机号吗& ...

  4. for循环与闭包

    Es5 function box(){ var arr = []; ;i<;i++){ arr[i] = (function(num){ //自我执行,并传参(将匿名函数形成一个表达式)(传递一 ...

  5. JS for循环 闭包

    对于for循环的闭包问题的理解,认为需要理解函数中的变量的作用域链的概念 另外提及下变量提升的概念 如下例子: var ar = [];for(var i=1:i<10; i++){ ar[i] ...

  6. JS中for循环里面的闭包问题的原因及解决办法

    我们先看一个正常的for循环,普通函数里面有一个for循环,for循环结束后最终返回结果数组 function box(){ var arr = []; for(var i=0;i<5;i++) ...

  7. 《你不知道的JavaScript》整理(一)——作用域、提升与闭包

    最近在读一本进阶的JavaScript的书<你不知道的JavaScript(上卷)>,里面分析了很多基础性的概念. 可以更全面深入的理解JavaScript深层面的知识点. 一.函数作用域 ...

  8. javascript中的闭包、模块与模块加载

    一.前言 闭包是基于词法作用域(  和动态作用域对应,词法作用域是由你写代码时,将变量写在哪里来决定的,因此当词法分析器处理代码时,会保持作用)书写代码时所产生的自然结果,甚至不需要为了利用闭包而有意 ...

  9. javascript最容易混淆的作用域、提升、闭包

    一.函数作用域 1.函数作用域 就是作用域在一个“Function”里,属于这个函数的全部变量都可以在整个函数的范围内使用及复用. function foo(a) { var b = 2; funct ...

随机推荐

  1. C++ 系列:typedef 和 #define 的区别

    总结一下typedef和#define的区别 1.概念 #define 它在编译预处理时进行简单的替换,不作正确性检查.它是预处理指令. typedef 它在自己的作用域内给一个已经存在的类型一个别名 ...

  2. Math: Fibonacci

    https://www.zhihu.com/question/28062458 http://blog.csdn.net/hikean/article/details/9749391 对于Fibona ...

  3. 在github上怎样克隆vue项目及运行

    长时间不做vue项目,今天看vue项目运行时有些指令忘记了,在这里写下相关指令 .克隆已有项目,一般情况项目中的README.md写的是项目运行步骤,一般项目的运行如下 克隆项目 git clone ...

  4. 分享一个现代的,免费的,简单而有效的编辑器Vis

    Vis是一个免费的开源,类似Vi的代码编辑器,它扩展了vi的模态编辑,内置支持使用相同编辑器的基于结构正则表达式的命令语言实现的多个游标/选择.并将其与基于sam结构正则表达式的命令语言相结合. Vi ...

  5. ssm框架,出现xxx不能加载,或者bean不能加载时的解决方案之一

    有可能是你在项目的mapper.xml文件中添加了本项目没有的实体类, 你把日志中找不到的最后一个实体类全项目搜索下,改成本项目可以引用的即可

  6. sql.xml 循环插入与修改写法

    // 插入 (交互一次数据库) <insert id="insertClient"> insert into m_linknodeclient (LinkClientI ...

  7. pyQT Dialog默认选中某一个选项问题的解决

    方法一: 在新建ui文件时不要新建Dialog # -*- coding: utf-8 -*- # Form implementation generated from reading ui file ...

  8. vs nuget 本地安装 nupkg包

    Install-Package fluentnhibernate -Source C:\Users\Alex\AppData\Local\NuGet\Cache\ 包名 路径

  9. solusvm 主控端迁移

    难点在于solusvm被控端已经开了小鸡的情况. 备份数据库: #!/bin/sh ## Vars CONF=/usr/local/solusvm/includes/solusvm.conf FILE ...

  10. 数据挖掘-diabetes数据集分析-糖尿病病情预测_线性回归_最小平方回归

    # coding: utf-8 # 利用 diabetes数据集来学习线性回归 # diabetes 是一个关于糖尿病的数据集, 该数据集包括442个病人的生理数据及一年以后的病情发展情况. # 数据 ...