为什么当我们用let定义循环变量时,不使用IFFE技术,我们可以在不丢失它的情况下将其特定值设置为函数



我阅读了有关constletvar的MDN页面。在ES2015之前,我们只有global scopefunction scope。在[此MDN页面][1]中,有一个块作用域优点的示例;这表明:没有使用闭包概念来保存函数的相关数据,比如循环迭代次数,而是将循环变量定义为let。如果let关键字仅用于块范围界定,如何为我们提供此功能?其他编程语言有这个概念吗?

let divClassX = document.querySelectorAll('.x');
for (let j = 0; j < 2; j++) {
divClassX[j].onclick = function (event) {
console.log('class x div's x ' + j)
}
}

上述代码具有与相同的功能

let divClassX = document.querySelectorAll('.x');
for (var j = 0; j < 2; j++) {
divClassX[j].onclick = (function (j) {
return function (event) {
console.log('class x div's x ' + j)
}
})(j)
}

我假设存在一些类似的功能,所以blow代码必须像上面一样工作,但当我两次点击div1或div2时,我都会得到2,但当点击div1时,我会得到一个,当点击div2时会得到两个。

let div1 = document.querySelector('#div1');
let div2 = document.querySelector('#div2');
let i = 1;
div1.onclick = function (event) {
console.log(i);
}
i = i + 1;
div2.onclick = function (event) {
console.log(i);
}

存在什么我不知道的概念?[1] :https://developer.mozilla.org/en-US/docs/Glossary/IIFE

与其说是修改变量的顺序,不如说是定义变量的作用域

在上一个示例中,let i出现在全局范围中。作为事件侦听器创建的每个function都会创建自己的作用域,其父作用域是全局作用域。创建函数时i的值是多少并不重要,重要的是作用域链的结构。JavaScript在越来越大的范围中查找变量;链";父作用域的。对于这两个函数,当在调用函数时访问时,i将解析为全局作用域,而不是在创建函数时。

至于使用let的循环,我认为let的部分设计目标是使循环/事件处理程序(或其他嵌套函数(的行为更加直观,并提供一种简单的方法来避免常见问题,即每个事件处理程序引用i最后值,而不是创建函数时的值(即在循环的每次迭代时(。

换句话说,在ES2015中,循环的每个迭代都有一个单独的作用域,let将变量分配给该作用域,而不是分配给周围的function或像var这样的全局作用域。此外,当调用嵌套函数(位于for循环内的函数(时;迭代";在查找作用域链时,首先查找作用域,因此它看到的i与迭代时一样。

它被称为闭包。

闭包是捆绑在一起的函数的组合(封闭(以及对其周围状态(词汇环境(的引用。在里面换句话说,闭包使您可以访问外部函数的作用域来自内部功能。在JavaScript中,每次都会创建闭包在函数创建时创建函数。

在您的最后一段中

console.log(i);

不打印副本,而是实际变量i(引用(,它是用初始化的

let i = 1;

并用进行了修改

i = i + 1;

相关内容

最新更新