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 定义执行图
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释放,就是闭包
-
释放指的是上下文,是栈