请解释这两个代码块在事件循环中的输出之间的区别?
Please explain the difference between the output of these two code blockes in event-loops?
我正在学习事件循环 JavaScript 但我发现在事件循环代码块中使用关键字 let 和 var 的这种未知行为。但是当使用它们简单的循环时它们工作得很好。
请在这方面帮助我。代码块如下:
for (let i = 0; i < 5; i++) {
setTimeout(() => {
console.log("let keyword output : ", i);
}, 0);
}
for (var i = 0; i < 5; i++) {
setTimeout(() => {
console.log("var keyword output : ", i);
}, 0);
}
他们的输出分别如下:
let keyword output : 0
let keyword output : 1
let keyword output : 2
let keyword output : 3
let keyword output : 4
var keyword output : 5
var keyword output : 5
var keyword output : 5
var keyword output : 5
var keyword output : 5
区别在于 var
和 let
变量的范围。
在 var
中,您有一个函数作用域,因此只有一个共享绑定。使用 let
你有一个块作用域,你每次迭代都会得到一个新的绑定。
由于闭包,您在循环内声明的函数可以访问其作用域和父作用域中的所有变量,直到垃圾收集器打开。
可以在 this 已回答的问题中找到更多详细信息。
当您使用“var”定义变量时,您的变量作用域是函数作用域,或者如果它是在函数外部声明的,那么它就是全局作用域。
在您的示例中,首先将执行所有同步代码,并且所有 setTimeOut() 将被移动到“回调队列”,然后在所有同步代码完成并且 main 清除之后,setTimeOuts(异步代码)将被推送到 main 并执行一个一个 .
变量:
当你像我提到的那样用“var”删除“i”时,它的功能范围是和
因为“i”的声明不在不同的函数中
全局范围和所有日志的值将是最后一个值“for”
分配给它的循环 (5).
让 :
当你用“let”声明“i”时,它是块范围,因为日志在
不同的块每个日志的“i”值会不同。
“let”和“var”的区别与事件循环无关
这个异步示例只是向您展示了不同之处。
试试这个你会看到“j”的值对于每个日志都是不同的:
for (var i = 0; i < 5; i++) {
let j = i;
setTimeout(() => {
console.log("var keyword output : ", i, j);
}, 0);
}
这意味着“i”在每次迭代中都有不同的值,但因为它的值在下一次迭代中被覆盖,而且它是全局范围的,所有日志记录的值都是最后一个并且是相同的
我正在学习事件循环 JavaScript 但我发现在事件循环代码块中使用关键字 let 和 var 的这种未知行为。但是当使用它们简单的循环时它们工作得很好。 请在这方面帮助我。代码块如下:
for (let i = 0; i < 5; i++) {
setTimeout(() => {
console.log("let keyword output : ", i);
}, 0);
}
for (var i = 0; i < 5; i++) {
setTimeout(() => {
console.log("var keyword output : ", i);
}, 0);
}
他们的输出分别如下:
let keyword output : 0
let keyword output : 1
let keyword output : 2
let keyword output : 3
let keyword output : 4
var keyword output : 5
var keyword output : 5
var keyword output : 5
var keyword output : 5
var keyword output : 5
区别在于 var
和 let
变量的范围。
在 var
中,您有一个函数作用域,因此只有一个共享绑定。使用 let
你有一个块作用域,你每次迭代都会得到一个新的绑定。
由于闭包,您在循环内声明的函数可以访问其作用域和父作用域中的所有变量,直到垃圾收集器打开。
可以在 this 已回答的问题中找到更多详细信息。
当您使用“var”定义变量时,您的变量作用域是函数作用域,或者如果它是在函数外部声明的,那么它就是全局作用域。 在您的示例中,首先将执行所有同步代码,并且所有 setTimeOut() 将被移动到“回调队列”,然后在所有同步代码完成并且 main 清除之后,setTimeOuts(异步代码)将被推送到 main 并执行一个一个 .
变量: 当你像我提到的那样用“var”删除“i”时,它的功能范围是和 因为“i”的声明不在不同的函数中 全局范围和所有日志的值将是最后一个值“for” 分配给它的循环 (5).
让 : 当你用“let”声明“i”时,它是块范围,因为日志在 不同的块每个日志的“i”值会不同。
“let”和“var”的区别与事件循环无关 这个异步示例只是向您展示了不同之处。 试试这个你会看到“j”的值对于每个日志都是不同的:
for (var i = 0; i < 5; i++) {
let j = i;
setTimeout(() => {
console.log("var keyword output : ", i, j);
}, 0);
}
这意味着“i”在每次迭代中都有不同的值,但因为它的值在下一次迭代中被覆盖,而且它是全局范围的,所有日志记录的值都是最后一个并且是相同的