经典的案例

let arr = []
for(var i =0;i<=5;i++){
arr[i]= function fn(){
console.log(i)
}
}
arr[0]() //6

解析:我们的想法是arr[0]的函数应该是打印0的,而且每个元素的函数都能打印出自己的索引才对,可结果出乎意料。实际上为啥是6,我们先逐步分析。

1.js没有块级作用域

for(var i =0;i<=5;i++){
b=3
console.log(i)
}
{var a =1}
console.log('结果:',a,b) //结果: 1 3

也就是说,在大括号中声明的变量在大括号外部能拿到。这些变量是全局变量。

2.函数操作的变量值是函数调用时的而非函数声明时的

var a = 1
var fn = function(){
console.log('a:',a)
}
a=2
fn() //a:2

函数声明时变量a的值是1,声明后a的值变成了2,此时再调用fn函数,取得的a是2.

3.for循环的变量泄漏

let arr = []
for(var i =0;i<=5;i++){
arr[i]= function fn(){
console.log('i',i)
}
}
//实际上此时的arr是,[fn,fn,fn,fn,fn,fn]
console.log('i:',i) //i:6
arr[0]() //i 6
//实际上就是 console.log('i',i),而此时的i变成了6,无论是数组的第几个元素,最终打印的都是6

如果我希望每个元素都是打印它的索引,如何解决这个问题

方案1:闭包

返回一个函数,实际上就是我希望函数里打印的变量时当时循环的i的值,那我就把这个值作为参数传进去.所以,我用函数去返回一个函数

let arr = []
for(var i =0;i<=5;i++){
var fn = function(a){
return function(){
console.log('i',a) //打印的并不是全局变量i,而是实参'i'
}
}
arr[i]= fn(i) //调用的时候,i是当前循环的值
}
arr[0]() //i 0

我们常说闭包可以用来延长变量的使用寿命,实际上就是单独用一个函数作用域去保存外部变量值.

方案2:let和const

let和const声明的变量常被视为块级作用域,即虽然js无块级作用域的说法,但是let 和const的功能可以被视作块级作用域

let arr = []
for(let i =0;i<=5;i++){
arr[i]= function fn(){
console.log('i:',i)
}
}
arr[0]() //i 0

如下:

let arr = []
{let a = 1
arr[0] =function (){
console.log('a:',a)
}}
{let a =2
arr[1] = function(){
console.log('a::',a)
}}
arr[0]() //a: 1
arr[1]() //a:: 2

说明,let声明的变量,在一个大括号里是可以视作独立的存在的。类似块级作用域的效果,如果把let换成var,那就会提升为全局变量,最后被后面的赋值修改。

for循环中的变量泄漏的更多相关文章

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

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

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

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

  3. 用闭包解决 js 循环中函数变量暂存问题

    需求:有一个数组,根据数组的值渲染对应的数字div,单击对应的div 在控制台打印对应的数字.如点击1,控制台打印1. 问题: 不管点击哪个值 打出来都是4 代码如下 <!DOCTYPE htm ...

  4. Python语言程序设计之一--for循环中累加变量是否要清零

    最近学到了Pyhton中循环这一章.之前也断断续续学过,但都只是到了函数这一章就停下来了,写过的代码虽然保存了下来,但是当时的思路和总结都没有记录下来,很可惜.这次我开通了博客,就是要把这些珍贵的学习 ...

  5. 16.1 foreach 循环中捕获变量的变化

    在 foreach 循环内的匿名函数(通常为Lambda表达式)中捕获循环 变量时要格外小心.代码清单16-1就展示了这样一个简单的示例,它看上去似乎会输出 x . y . z . string[] ...

  6. 关于在for循环中绑定事件打印变量i是最后一次。

    其实函数引用的外部变量都是最后一次的值. <!DOCTYPE html> <html lang="en"> <head> <meta ch ...

  7. 关于while read line 循环中变量作用域的问题

    前一阵用shell写了一个从数据库中抽取数据生成.xml文件的脚本,要求是每个文件中只生成1000条数据.于是用到了while read line 作为循环. 在制作文件计数器的时候发现了一个问题,在 ...

  8. 注意for循环中变量的作用域-乾颐堂

    1 2 for e in collections:     pass 在for 循环里, 最后一个对象e一直存在在上下文中.就是在循环外面,接下来对e的引用仍然有效. 这里有个问题容易被忽略,如果在循 ...

  9. 注意for循环中变量的作用域

    for e in collections: pass 在for 循环里, 最后一个对象e一直存在在上下文中.就是在循环外面,接下来对e的引用仍然有效. 这里有个问题容易被忽略,如果在循环之前已经有一个 ...

随机推荐

  1. 菜鸡的Java笔记 生产者与消费者

    生产者与消费者        代码要求知道做什么用即可        线程间的通讯问题以及 Object 类的支持            基础模型        现在希望实现一种数据的生产和取出的操作 ...

  2. 微信小程序(九)

    小程序运行环境与基本架构 每个小程序都是运行在它所在的微信客户端上的,通过微信客户端给它提供的运行环境,小程序可以直接获取微信客户端的原生体验和原生能力. wxml视图文件和wxss样式文件都是对渲染 ...

  3. [luogu5616]恶魔之树

    记录$lcm$的质因子状态(包括大于$\sqrt 300$的质因子),设$f[s]$表示质因子状态为$s$的$lcm$之和,转移枚举当前的数$k$,转移到$lcm(s,k)$即可,时间复杂度为$o(n ...

  4. [luogu5665]划分

    暴力dp,用f[i][j]表示前i个数,最后一个区间是(j,i]的最小答案,转移方程用可以用前缀和来优化,复杂度为$o(n^3)$(然后可以各种优化到$o(n^2)$,但这不需要)输出f[i][j], ...

  5. 抽象类和接口的区别详解、package和import

    1.抽象类和接口以及抽象类和接口的区别. 1.1.抽象类的基础语法(见昨天笔记) 1.2.接口的基础语法 1.接口是一种"引用数据类型". 2.接口是完全抽象的. 3.接口怎么定义 ...

  6. 基于Vue简易封装的快速构建Echarts组件 -- fx67llQuickEcharts

    fx67llQuickEcharts A tool to help you use Echarts quickly! npm 组件说明 这本来是一个测试如何发布Vue组件至npm库的测试项目 做完之后 ...

  7. IntelliJ IDEA 2021.3 正式发布:支持远程开发、IDE故障排查等多项优化改进

    作者:程序猿DD 博客:https://blog.didispace.com/ 昨天刚刚跟大家聊了Jetbrains即将推出轻量级编辑器Fleet,以挑战 VS Code的消息,今天又收到了Intel ...

  8. Codeforces 1392I - Kevin and Grid(平面图的欧拉定理+FFT)

    Codeforces 题面传送门 & 洛谷题面传送门 模拟赛考到一道和这题有点类似的题就来补了 神仙 GLBR I %%%%%%%%%%%%%%%%%%%% 不过感觉见过类似的题目之后就比较套 ...

  9. 【转】群体研究套路:开心果denovo+重测序+转录组+群体进化+选择位点

    转自公众号Eric生信小班.学习群体遗传套路 中科院昆明动物园吴东东研究团队联合国外研究团队2019年在Genome Biology发表题为Whole genomes and transcriptom ...

  10. 31-Longest Common Prefix

    Longest Common Prefix My Submissions Difficulty: Easy Write a function to find the longest common pr ...