问题描述
我已经学习了 JavaScript 中变量提升的基础知识,现在正在尝试通过做一些练习来增强它。我遇到了这段代码:
function makeAdders(lst) {
var ar = [];
for(var i = 0; i < lst.length; i ++) {
var n = lst[i];
ar[i] = (x) => x + n;
}
return ar;
}
var adders = makeAdders([6,3,5]);
adders.forEach((adder) => {
console.log(adder(100));
})
这段代码首先从给定的列表中创建一个函数数组。每个函数将相同的传递数字(在本例中为 100)添加到列表的特定值并打印结果。预期的输出是:106、103、105,如果在 for 循环中使用“let”而不是“var”,则可以实现这一点。不过,上面代码的输出是 105、105、105,经过一些研究,我得出的结论是,这是因为变量 i 和 n 被提升了(因为 var 被提升而 let 没有被提升)。>
然而,我无法完全理解这里到底发生了什么,以及这段代码中的变量提升如何阻止它达到预期的结果。有人可以帮我了解这里到底发生了什么吗?提前致谢!
解决方法
var
提升基于 file
(如果变量在全局范围内)或 function
(如果变量在函数内)
let
不会提升并被劫持(仅作用域)到最近的大括号 {
... }
代码有 n
被提升(不是到 {...body of for...}
内的 for 作用域)而是被提升到 makeAdders
函数的作用域
现在当代码
var adders = makeAdders([6,3,5]);
被执行了,我们有一组加法器function
,它们都有closure
到一个共享的n
变量
(closure
是指函数可以访问其词法作用域,即使它是在完全另一个作用域中执行的)
n
在所有 function
之间共享,最后一个 n
设置为输入数组 which happened to be 5 for now
中最后一个元素的值
这就是为什么在创建所有函数后 n
有 5
并且所有 adders
将返回 5 + x