js中非常简单的变量泄露问题

发布于 2022-09-07 00:05:06 字数 472 浏览 14 评论 0

var a = [];
for (var i = 0; i < 10; i++) {
  a[i] = function () {
    console.log(i);
  };
}
a[6](); // 10

变量泄露导致上面的a[6]变成10;
我不太理解 这里为什么a[6]是10,我的错误思维如下

  1. a[6] 这里没有变量, 所以内存泄露源于循环
  2. 循环中,每次都是把当前次数赋值给对应的数组,

a[0] = function () { console.log(0);};
a[1] = function () { console.log(1);};
......
a[9] = function () { console.log(9);};
再每一次赋值的时候i的值是正确的,赋值后,每个函数都是固定输出一个数字,也不存在变量
3.请问 我的思维错在哪里了

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

我很OK 2022-09-14 00:05:06

这个题已经问烂了也回答不知道多少遍了
i是全局变量 函数调用的时候获取i 此时 i已经循环到了10
下面是个简单了例子可以理解为经历了两次循环

var i = 1;
function a1(){ console.log(i) }

var i = 2;
function a2(){ console.log(i) }

a1();//2
a2();//2

解决方法 将i变为局部变量

es6
{
  let i = 1;
  function a1(){ console.log(i) }
}

{
  let i = 2;
  function a2(){ console.log(i) }
}

a1();//1
a2();//2
//es6 let局部变量
for(let i=0;i<10;i++) ...
//or
//自执行函数 es5中只有函数内有局部作用域 
for (var i = 0; i < 10; i++) {
  a[i] = (function(i){
      return function () {
            console.log(i);
          };
  })(i)
}
只有一腔孤勇 2022-09-14 00:05:06

问题源于对函数作用域(链)的理解不够深,一下是个人的一点见解,望能帮助到您:

    var a = [];
    for (var i = 0; i < 10; i++) {   // 此处变量i为全局变量,属于外层作用域(window)
      // 此处声明函数,创建函数的作用域(建立作用域链,函数内部能访问外层作用域中的i变量,但此处只是声明,并不执行)
      a[i] = function () {     
        // 函数内部并未定义i变量,当函数执行时通过声明函数时建立的作用域链向上查找变量i
        // 调用a[6]时,for循环已经结束,变量i已经变成10,所以此处打印输出 10
        console.log(i);   
      };
    }
    a[6](); // 10
懷念過去 2022-09-14 00:05:06

执行a[6]()的时候,i已经循环到了10了

撧情箌佬 2022-09-14 00:05:06

闭包问题,同学你的基础要加油了.

若言繁花未落 2022-09-14 00:05:06

其实 es6 的 let 根本没抓住问题的本质

关键在于 js 作为一个允许副作用的语言,它的 closure 却只支持引用外层作用域的变量,而不支持「引用」外层作用域中变量的值

C++ 就没有这个问题~

#include <functional>
#include <iostream>

using namespace std;

int main() {
  function<void()> a[10];
  for (int i = 0; i < 10; i++) {
    a[i] = [i] () {
      cout << i << '\n';
    };
  }
  a[6](); // 6
}

之所以出现这个反直觉的现象,就是因为你那 10 个函数引用的都是同一个 i 变量,而这个变量的值是 for 循环最后一次执行时的值,也就是 10。

岁吢 2022-09-14 00:05:06

简单的闭包问题,我面试的时候都被问到过好几次了。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文