深入理解了闭包的形成过程

原文 JavaScript深入之闭包 再次感谢 冴羽

定义

闭包是指那些能够访问自由变量的函数。

  • 自由变量: 自由变量是指在函数中使用的,但既不是函数参数也不是函数的局部变量的变量。

    闭包

    闭包 = 函数 + 函数能够访问的自由变量

var scope = "global scope";
function checkscope(){
    var scope = "local scope";
    function f(){
        return scope;
    }
    return f;
}

var foo = checkscope();
foo();

解析执行过程:

  1. 进入全局代码,创建全局执行上下文,全局执行上下文压入执行上下文栈
  2. 初始化全局执行上下文
  3. 执行 checkscope 函数,创建 checkscope 函数执行上下文,checkscope 执行上下文被压入执行上下文栈
  4. checkscope 函数执行上下文初始化,创建 AO, this, 等
  5. checkscope 函数执行完毕, 弹出checkscope 执行上下文 (这里被弹出后checkscope 函数就被销毁了)
  6. f 函数 执行上下文初始化,创建 AO, this, 等 7.f 函数执行完毕, 弹出 f 函数的执行上下文

以上, 函数 checkscope 被销毁之后还是可以访问到checkscope函数作用域下的 scope 值, 说明 f 函数引用了 checkscope 的执行上下文中的 AO, 即使checkscope函数被销毁了, 但是 checkscope 执行上下文的 AO 仍然存在内存中, f 函数通过自身的作用域链向上查找依然可以取到这个值, 这就实现了闭包

题目I

var data = [];

for (var i = 0; i < 3; i++) {
  data[i] = function () {
    console.log(i);
  };
}

data[0](); // 3
data[1](); // 3
data[2](); // 3

题目 II

var data = [];

for (var i = 0; i < 3; i++) {
  data[i] = (function (i) {
        return function(){
            console.log(i);
        }
  })(i);
}

data[0](); // 0
data[1](); // 1
data[2](); // 2

题目 III

var data = [ ];
for( var i=0; i<3 ; i++ ){
        data [ i ] = function ( ) {
            console.log ( i );
        };
       data [ i ]( i );
}
data[0](); // 0
data[1](); // 1
data[2](); // 2

题目 IIII

for (var i = 1; i <= 5; i++) {
    setTimeout((function(i) {
        return function() {
            console.log(i)
        }
    })(i), i * 1000)
}
// 每隔一秒按照顺序打印一次 1 -> 5

以上只是自己做个记录, 题目代码解析没有写, 后续有时间再补上