for循环中的变量泄漏
经典的案例
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循环中的变量泄漏的更多相关文章
- js for 循环中的 变量问题。
今日处理项目中的一个循环,本来就是一个小小的for循环,后来发现该段程序出现了问题,仔细检查代码没有发现其中的错误.无奈只好叫来了老大帮忙.通过在模版中断点调试(该方式只能自己写debugger断点) ...
- 【SQL】小心在循环中声明变量——浅析SQL变量作用域
本文适用:T-SQL(SQL Server) 先看这个语句: --跑3圈 BEGIN --每圈都定义一个表变量,并插入一行 DECLARE @t TABLE(Col INT PRIMARY KEY) ...
- 用闭包解决 js 循环中函数变量暂存问题
需求:有一个数组,根据数组的值渲染对应的数字div,单击对应的div 在控制台打印对应的数字.如点击1,控制台打印1. 问题: 不管点击哪个值 打出来都是4 代码如下 <!DOCTYPE htm ...
- Python语言程序设计之一--for循环中累加变量是否要清零
最近学到了Pyhton中循环这一章.之前也断断续续学过,但都只是到了函数这一章就停下来了,写过的代码虽然保存了下来,但是当时的思路和总结都没有记录下来,很可惜.这次我开通了博客,就是要把这些珍贵的学习 ...
- 16.1 foreach 循环中捕获变量的变化
在 foreach 循环内的匿名函数(通常为Lambda表达式)中捕获循环 变量时要格外小心.代码清单16-1就展示了这样一个简单的示例,它看上去似乎会输出 x . y . z . string[] ...
- 关于在for循环中绑定事件打印变量i是最后一次。
其实函数引用的外部变量都是最后一次的值. <!DOCTYPE html> <html lang="en"> <head> <meta ch ...
- 关于while read line 循环中变量作用域的问题
前一阵用shell写了一个从数据库中抽取数据生成.xml文件的脚本,要求是每个文件中只生成1000条数据.于是用到了while read line 作为循环. 在制作文件计数器的时候发现了一个问题,在 ...
- 注意for循环中变量的作用域-乾颐堂
1 2 for e in collections: pass 在for 循环里, 最后一个对象e一直存在在上下文中.就是在循环外面,接下来对e的引用仍然有效. 这里有个问题容易被忽略,如果在循 ...
- 注意for循环中变量的作用域
for e in collections: pass 在for 循环里, 最后一个对象e一直存在在上下文中.就是在循环外面,接下来对e的引用仍然有效. 这里有个问题容易被忽略,如果在循环之前已经有一个 ...
随机推荐
- 菜鸡的Java笔记 生产者与消费者
生产者与消费者 代码要求知道做什么用即可 线程间的通讯问题以及 Object 类的支持 基础模型 现在希望实现一种数据的生产和取出的操作 ...
- 微信小程序(九)
小程序运行环境与基本架构 每个小程序都是运行在它所在的微信客户端上的,通过微信客户端给它提供的运行环境,小程序可以直接获取微信客户端的原生体验和原生能力. wxml视图文件和wxss样式文件都是对渲染 ...
- [luogu5616]恶魔之树
记录$lcm$的质因子状态(包括大于$\sqrt 300$的质因子),设$f[s]$表示质因子状态为$s$的$lcm$之和,转移枚举当前的数$k$,转移到$lcm(s,k)$即可,时间复杂度为$o(n ...
- [luogu5665]划分
暴力dp,用f[i][j]表示前i个数,最后一个区间是(j,i]的最小答案,转移方程用可以用前缀和来优化,复杂度为$o(n^3)$(然后可以各种优化到$o(n^2)$,但这不需要)输出f[i][j], ...
- 抽象类和接口的区别详解、package和import
1.抽象类和接口以及抽象类和接口的区别. 1.1.抽象类的基础语法(见昨天笔记) 1.2.接口的基础语法 1.接口是一种"引用数据类型". 2.接口是完全抽象的. 3.接口怎么定义 ...
- 基于Vue简易封装的快速构建Echarts组件 -- fx67llQuickEcharts
fx67llQuickEcharts A tool to help you use Echarts quickly! npm 组件说明 这本来是一个测试如何发布Vue组件至npm库的测试项目 做完之后 ...
- IntelliJ IDEA 2021.3 正式发布:支持远程开发、IDE故障排查等多项优化改进
作者:程序猿DD 博客:https://blog.didispace.com/ 昨天刚刚跟大家聊了Jetbrains即将推出轻量级编辑器Fleet,以挑战 VS Code的消息,今天又收到了Intel ...
- Codeforces 1392I - Kevin and Grid(平面图的欧拉定理+FFT)
Codeforces 题面传送门 & 洛谷题面传送门 模拟赛考到一道和这题有点类似的题就来补了 神仙 GLBR I %%%%%%%%%%%%%%%%%%%% 不过感觉见过类似的题目之后就比较套 ...
- 【转】群体研究套路:开心果denovo+重测序+转录组+群体进化+选择位点
转自公众号Eric生信小班.学习群体遗传套路 中科院昆明动物园吴东东研究团队联合国外研究团队2019年在Genome Biology发表题为Whole genomes and transcriptom ...
- 31-Longest Common Prefix
Longest Common Prefix My Submissions Difficulty: Easy Write a function to find the longest common pr ...