`
ldl_xz
  • 浏览: 68793 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

js闭包,解决for循环变量未定义等类似问题

 
阅读更多

循环中的闭包 一个常见的错误出现在循环中使用闭包,假设我们需要在每次循环中调用循环序号

for(var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i);  
    }, 1000);
}

上面的代码不会输出数字 0 到 9,而是会输出数字 10 十次。

当 console.log 被调用的时候,匿名函数保持对外部变量 i 的引用,此时 for循环已经结束, i 的值被修改成了 10.

为了得到想要的结果,需要在每次循环中创建变量 i 的拷贝。

避免引用错误

为了正确的获得循环序号,最好使用 匿名包裹器(译者注:其实就是我们通常说的自执行匿名函数)。

for(var i = 0; i < 10; i++) {
    (function(e) {
        setTimeout(function() {
            console.log(e);  
        }, 1000);
    })(i);
}

外部的匿名函数会立即执行,并把 i 作为它的参数,此时函数内 e 变量就拥有了 i 的一个拷贝。

当传递给 setTimeout 的匿名函数执行时,它就拥有了对 e 的引用,而这个值是不会被循环改变的。

有另一个方法完成同样的工作;那就是从匿名包装器中返回一个函数。这和上面的代码效果一样。

for(var i = 0; i < 10; i++) {
    setTimeout((function(e) {
        return function() {
            console.log(e);
        }
    })(i), 1000)
}

转载自:http://www.9958.pw/post/js_bibao

分享到:
评论

相关推荐

    javascript常见错误

    由于闭包共享循环变量 `i` 的引用,而非其值,所以在循环结束后,所有的闭包中的 `i` 都指向了最后一个值。 **解决方案**: 为每个闭包提供独立的变量环境,可以通过立即执行函数表达式(IIFE)来实现: ```...

    最容易犯的JavaScript错误.doc

    在循环中创建闭包可能导致意外的结果,因为每个闭包都会捕获循环变量的引用,而不是它的值。解决这个问题通常需要创建一个立即执行的函数表达式(IIFE),以确保每个闭包有自己的局部变量副本。例如: ```...

    JavaScript入门常见问题解决方案简介.docx

    ### JavaScript入门常见问题解决方案知识点详解 #### 一、JavaScript简介 **知识点1:JavaScript是什么?** - **定义:** - JavaScript是一种轻量级、解释型的编程语言。 - 主要用于网页客户端脚本,支持事件...

    js常见问题集.docx

    在文档"js常见问题集.docx"中,提到了一些常见的JS问题及其解决方案,我们将详细探讨这些话题,并进一步扩展相关的JavaScript知识。 1. **常数未赋初值** 在ES6中,`const`用于声明不可变的常量。如果忘记在声明时...

    javascript学习之闭包分析

    这些匿名函数在循环结束后依然保持对循环变量`i`的引用,这就形成了闭包。然而,由于JavaScript的动态作用域特性,所有函数都共享同一个`i`变量。当循环结束,`i`的值变为4,因此,当我们后来调用`arr[i]()`时,所有...

    JSjavascript包

    2. 控制结构:包括条件语句(if...else、switch)、循环(for、while、do...while)和跳转语句(break、continue)。 3. 函数:JavaScript函数是第一类对象,可以作为参数传递,也可以作为返回值。函数表达式(匿名...

    You Don't Know JS(高清带目录中文版)1-3

    《You Don't Know JS》是一套著名的JavaScript编程书籍,由Kyle Simpson撰写,旨在深入解析JavaScript的各个核心概念,帮助开发者真正理解这门语言的精髓。本资源提供了高清中文版的第1-3部分,分别是“3this与对象...

    JavaScript程序设计基础教程》习题答!!

    在《JavaScript程序设计基础教程》的习题解答中,学生将有机会实践以上提到的各个方面,通过解决实际问题来加深对JavaScript的理解。通过不断练习和应用,你可以熟练掌握JavaScript编程技能,为Web开发打下坚实基础...

    常用JavaScript300例

    1. **Undefined**:表示变量未定义或函数无返回值。 2. **Null**:表示一个空的引用,通常用于设置变量为无值状态。 3. **Boolean**:包含两个值,true和false,用于逻辑判断。 4. **Number**:用于数值计算,支持...

    javascript语法备忘.doc

    此外,JavaScript 还提供了数组、对象、函数表达式、箭头函数、闭包等高级特性,以及异步编程的回调函数、Promise 和 async/await 等机制,这些在实际开发中非常关键。理解并熟练运用这些基础知识,将有助于编写出...

    Web-前端教程37 JS进阶:作用域.zip

    在ES6之前,JavaScript并没有真正的块级作用域,但ES6引入了`let`和`const`关键字,使得在`if`语句、`for`循环等代码块内可以创建块级作用域。这解决了过去使用`var`声明变量时可能出现的意外变量提升问题。 四、...

    js作用域基本介绍.doc

    ES6 引入了 `let` 关键字,允许在块级作用域(如 `if` 语句、`for` 循环等)中定义变量。这与 `var` 不同,`var` 定义的变量在函数作用域内,而 `let` 定义的变量仅在它所在的块级作用域内有效。 6. **立即执行...

    查找并修复JavaScript代码中的问题.zip

    使用try/catch语句捕获异常,以及记录和报告错误信息,可以帮助定位和解决问题。 压缩包中的`eslint_main.zip`可能是一个配置了特定规则的ESLint实例,ESLint是一个静态代码分析工具,它可以检查代码风格、潜在错误...

    常用JS大全,Javascript技术文章

    1. **基础语法**:JavaScript的基础包括变量、数据类型(如字符串、数字、布尔值、null、undefined、对象和数组)、操作符(算术、比较、逻辑、三元)、流程控制(条件语句、循环)以及函数。 2. **面向对象**:...

    JavaScript 参考手册集合 chm版打包

    此外,JavaScript还有作用域、闭包、原型链、事件处理、异步编程(回调函数、Promise、async/await)等高级主题。学习这些内容可以帮助开发者深入理解JavaScript的运行机制,并提升编写高效代码的能力。 在提供的...

    What-is-Scope.pdf.zip_javascript

    现在,`if`语句、`for`循环、`switch`语句等代码块内的变量声明会创建一个块级作用域,这些变量只在该块内可见。 5. **函数作用域与块级作用域的区别** 函数作用域在函数定义时创建,而块级作用域在代码块执行时...

    JS相关杂项

    6. **异步编程**:包括回调函数、Promise、async/await等,用于解决JavaScript的单线程模型下处理I/O操作的问题。Promise是处理异步操作的新方式,async/await则提供了更简洁的异步编程语法。 7. **DOM操作**:...

    关于JS中setTimeout()无法调用带参函数问题的解决方法.docx

    在JavaScript编程中,`setTimeout()`函数常用于设置一个定时任务,它会在指定的毫秒数后执行一个函数或表达式。...在实际开发中,还应注意避免全局变量污染、确保定时器的正确管理和内存泄漏等问题。

Global site tag (gtag.js) - Google Analytics