作用域运行解析

73 阅读2分钟
let i = 1;
let fn = function(i) {
    return function (n) {
        return console.log(n + (++i));
    }
}
let f = fn(1);
f(2); // 4
fn(3)(4); // 8
f(5); // 8
console.log(i); // 1

步骤解析:

  • 1、程序运行时,就有了执行环境栈ECStack,以及当前的执行上下文【执行环境】EC(G)
  • 2、当前全局环境VO(G)中,创建一个变量i,创建一个值1,然后将变量i与值1关联
  • 3、声明一个函数fn,其作用域就在当前的VO(G)
  • 4、创建一个变量f,运行fn函数,并传参1
  • 5、在堆栈中开辟一个内存地址为AAAFFF000,里面有形参i = 1,以及一个匿名函数,并且为其创建一个作用域AO
  • 6、变量f与fn的引用关联
  • 7、运行f(2),开辟一个内存地址为AAAFFF111,并把参数2传入内存地址为AAAFFF111的函数中,因此形参n为2,打印n + (++i),由于在当前AAAFFF111中没有变量i,则向上查询在AAAFFF000的作用域里找到i,i值变为2,因此f(2)打印结果为4
  • 8、运行fn(3)(4),运行fn,开辟一个内存地址为AAAFFF222,并把参数3传入内存地址为AAAFFF222的函数中,因此形参i为3。运行AAAFFF222里的匿名函数,参数为4,开辟一个内存地址为AAAFFF333的空间,n为4,打印n + (++i),因为当前AAAFFF333里面没有变量i,则向上查询在AAAFFF222的作用域里找到i,i值变为4,因此f(3)(4)打印结果为8
  • 9、运行f(5),开辟一个内存地址为AAAFFF444的空间,并把参数5传入内存地址为AAAFFF444的函数中,因此形参为5,打印n + (++i),由于当前AAAFFF444里面没没有变量i,则向上查询在AAAFFF000的作用域里找到i,i值变为3,因此f(5)打印结果为8;
  • 10、打印全局变量i,结果为1

作用域.jpg