经典的案例

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. Spark SQL知识点大全与实战

    Spark SQL概述 1.什么是Spark SQL Spark SQL是Spark用于结构化数据(structured data)处理的Spark模块. 与基本的Spark RDD API不同,Sp ...

  2. [cf1340D]Nastya and Time Machine

    记$deg_{i}$为$i$的度数,简单分类讨论可得答案下限为$\max_{i=1}^{n}deg_{i}$ 另一方面,此下限是可以取到的,构造方法较多,这里给一个巧妙一些的做法-- 对其以dfs(儿 ...

  3. [cf1209E]Rotate Columns

    题意也可以理解为这样一个过程: 对于每一列,将其旋转后选出若干行上的数,要求与之前的行都不同 用$g_{i,S}$表示第$i$列选出的行数集合为$S$的最大和,$f_{i,S}$表示前$i$列$S$中 ...

  4. HarmonyOS 3.0.0开发者预览版全新发布

    2021年10月22日在华为开发者大会HDC.Together 2021 主题演讲上,我们发布了HarmonyOS 3.0.0开发者预览版,主要内容包括:Harmony设计系统.ArkUI 3.0.A ...

  5. 联盛德 HLK-W806 (五): W801开发板上手报告

    目录 联盛德 HLK-W806 (一): Ubuntu20.04下的开发环境配置, 编译和烧录说明 联盛德 HLK-W806 (二): Win10下的开发环境配置, 编译和烧录说明 联盛德 HLK-W ...

  6. CF187D BRT Contract

    考虑如果哪次经过了红灯则显然已经和出发的时间没关系了. 然后我们需要做的是怎么样找到最近的一个是红灯的点. 然后实际下是我们做一个前缀和:\(L_i = \sum d_i\) 然后求\(\min (L ...

  7. Codeforces 286E - Ladies' Shop(FFT)

    Codeforces 题面传送门 & 洛谷题面传送门 好久没刷过 FFT/NTT 的题了,写篇题解罢( 首先考虑什么样的集合 \(T\) 符合条件.我们考察一个 \(x\in S\),根据题意 ...

  8. 一次forEach 中 await 的使用

    forEach 和 await/async 的问题 最近在刷面试提的时候看见这样一道题 const list = [1, 2, 3] const square = num => { return ...

  9. python-django-自定义查询Q函数和F函数

    数据库: def page_q(request): """Q函数的使用""" #查询username和nickname都是zhangsan ...

  10. 2020终于解决Chrome浏览器“崩溃啦”的问题!

    Google的chrome莫名其妙突然所有页面都显示"喔唷 崩溃啦",各种插件在右下角弹出报错!这个问题我之前遇到过一次,后来通过改快捷方式的名字解决了.可是这次,隔离回来上班,打 ...