[JS]02.closure例子分析

134 阅读1分钟

1. example1

let x = 5;
function fn(x) {
  return function(y) {
    console.log(y + (++x))
  }
}
let f = fn(6);
f(7);
fn(8)(9);
f(10);
console.log(x);

1.1 定义执行过程

  • 首先生成 Execution Context Stack 执行环境栈

  • 生成全局执行上下文 Execution Context(Global)

  • 全局变量 Varibale Object (Global) 存在EC(G)中

  • 变量定义

    • 普通变量以及对象地址,直接存在栈中
    • 对象变量存在堆中
      • 函数存在堆内存中
      • 函数创建一个作用域[[scope]],作用域在全局上下文EC(G)中
      • 包含形参,函数体字符串
  • let f = fn(6)

    • 函数执行,形成私有上下文EC(fn1)
    • 当前上下文变量, AO(fn1)
    • 初始化作用域链<EC(fn1), EC(G)>, 左端自己,右端上级
    • 形参赋值,x=6,形参是私有变量AO(fn1)中
    • 执行定义的函数字符串
    • 创建一个return的函数
    • 执行完的函数地址,赋值给f,f在全局作用域

1.2 定义执行图

image.png

1.3 额外知识点


// ++i 和 i++ 都是在自身的基础上累加1
// i++ 先拿原始的i值进行运算,运算结束后,i再累加1
// ++i 先让自身累加1,累加后拿最新的结果进行运算处理

let i = 1;
console.log(5 + (i++)) // 6
i = 1;
console.log(5 + (++i)) // 7

2. example2

let a = 0,
    b = 0;
function A(a) {
  A = function(b) {
    alert(a + b++);
  };
  alert(a++);
}
A(1);
A(2);
  • A 中的 A重新定义,修改了全局的A,函数重构

  • 第一次执行未重构的函数,执行a++ 输出1,a变成2

  • 第二次执行了重构的函数,a 变成了2 传入2 2+2 = 4

  • 闭包是一种机制

  • 当前上下文的某个东西,被当前上下文以外的占用,不能被GC释放,就是闭包

  • 释放指的是上下文,是栈

image.png