1、题目一
let x = 5;
function fn(x) {
return function (y) {
console.log(y + (++x));
}
}
let f = fn(6);
f(7); // 7+(6+1)= 14
fn(8)(9); //9+(8+1)= 18
f(10); //10+(7+1) = 18 注意此时这里的x已经是7,经过fn(6)后做了一次++x处理变成7保留着。
console.log(x); // 5
函数执行前需要做如下几个事情:
- 初始化作用域链[[scope]]: <当前上下文,函数的作用域(函数fn创建时候所处的上下文)>
- 初始化this指向
- 初始化arguments
- 形参赋值
- 变量提升
[一般情况下]
函数执行完成后,所形成的私有上下文,都会出栈”释放”。
- 私有上下文中的一切内容都会被销毁
- 优化栈内存空间
[特殊情况]
如果函数执行所形成的上下文中,如果出现引用类型的空间地址被当前上下文以外的事物所占用,那么当前上下文是不能够出栈释放的。
- 上下文中的信息保留下来(包含私有变量和值)
- 导致栈内存空间变大
下图中,0x000001被小f占用,堆内存不能够被释放。
EC(FN1) 代表fn(6)第一次执行。
f(7) -> 0x000001(7) 执行完后释放
EC(FN2)代表fn(8)第二次执行。 EC(FN2)是全新的,和EC(FN1) 没关系,fn(6)没有被释放。
f(8)(9) -> 0x000000(8) 先执行fn(8),返回结果 紧接着执行传递实参9, 0x000002(9) 。
堆0x000000 临时不会被出栈释放,因为返回的结果需要在外部用一次,等到0x000002(9) 执行完,再出栈释放。
f(10)->0x000001(10)
++i 和 i++
- 都是自身基础上累加1,累加和运算的顺序不一样
- i=1 5+(i++) 运算结果:6 i:2 “先运算在累加”
- i=1 5+(++i) i:2 运算结果:7 “先累加在运算”