javascript中 for(let i =0;...;...) 与let i=0;for(;....;...)循环的区别
var result = [],
a = 3
var total = 0
function foo(a) {
let i = 0
for (; i < 3; i++) {
result[i] = function () {
total += i * a
console.log(total)
}
}
}
foo(1)
result[0]() // 3
result[1]() // 6
result[2]() // 9
今天看到这样一道题,声明变量写在for循环括号外和写在里面居然有这么大的区别,大佬们能不能从执行上下文/作用域/作用域链/V8运行原理的基础上讲解一下
var result = [],
a = 3
var total = 0
function foo(a) {
for (let i = 0; i < 3; i++) {
result[i] = function () {
total += i * a
console.log(total)
}
}
}
foo(1)
result[0]() // 0
result[1]() // 1
result[2]() // 3
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
let 命名的变量仅在作用域内生效,第一个方法,let i作用域是foo方法内,第二个方法let i 的作用域是每一个for循环.
result数组里面的匿名闭包方法保存了局部变量i的引用
第一个方法 引用的i在for循环结束时已经变成3,所以result数组保存的每个result方法调用时都是使用了这个3
第二个方法,因为作用域是每个for循环,每一次for循环调用实际上都相当于一个新的let i定义,闭包方法保存了每次for循环时i的引用,这时相当于三个方法每个都保存了一个单独的i
所以你看到了这个结果
我说的可能不太清楚
你要了解的知识:let作用域,闭包 搞清楚这两个,你就清楚了
不同位置下let定义的作用域是不同的,在for内 和 for外 也存在这样的情况,比如:
你运行上述代码就可以找到规律啦。
这个是作用域的问题。
var 全局
let const 局部
以let来说,你定义在一个function中,那么他在这function中的任意位置都能被访问到,function外部则无法使用,而如果你是定义在for/swaich/forEach等循环体中,那他的生效范围只在该循环体里面,function里面循环体外面也无法获取该变量
let 写在 for 的循环头或循环里,每次循环对let都形成一个独立的作用域。for循环对var则形不成作用域。