2020年5月23日
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、EC(G)
0x101
[[scope]] -> VO(G)
fn(6)
执行2、EC(fn)
fn(6)
[[scopeChain]] -> VO(G)
{0:6}
0x102
3、EC
f(7)
-> scopeChain AO(fn)
-> 7+6+1 = 14 -> AO(fn)
(x=7)fn(8)(9)
-> 9+8+1 = 18 -> AO(fn)
(x=9)f(10)
-> 10+7+1 = 18console.log(x)
-> 54、结果:
14、18、18、5
测试运行情况:正确
个人认为考察点:
let a = 10;
-> 5 + (++a)
与 5 + (a++)
的区别,前者(++a)
+1完再返回,而后者则是直接返回此刻a
的值 -> 说白了,一个前置递增(level 16)与一个后置递增(level 17)的pklet x = 5;
function fn() {
return function(y) {
console.log(y + (++x));
}
}
let f = fn(6);
f(7);
fn(8)(9);
f(10);
console.log(x);
分析:
1、EC(G)
2、EC(fn)
{0:6}
return 0x102
3、结果
13、16、18、8
测试正确
个人认为考察点:
let a=0,
b=0;
function A(a){
A=function(b){
alert(a+b++);
};
alert(a++);
}
A(1);
A(2);
分析:
1、EC(G)
2、EC(A)
{0:1}
1
-> 1+1 = 2alert(a++)
-> 13、EC(A)
A(2)
{0:2}
2
-> 2+1 = 3alert(a+b++)
-> a+(b++)
-> 2+2 = 44、结果
1、4
测试正确
归纳一下自己如何分析:
EC(G)
和EC(函数)
0x101
、0x102
这样的过程我发现做了几道题后,不会写代码了,只会看这些代码……
var x = 3,
obj = {x: 5};
obj.fn = (function () {
this.x *= ++x;
return function (y) {
this.x *= (++x)+y;
console.log(x);
}
})();
var fn = obj.fn;
obj.fn(6);
fn(4);
console.log(obj.x, x);
分析:
1、EC(G)
J
作为前缀){x:5}
-> x:95
0xF101
obj.fn
-> 0xF101
obj.fn(6)
fn(4)
console.log(obj.x, x);
-> 95,2342、EC(fn)
this.x *= ++x
<=> window.x = (window.x) * (++x)
-> window.x
= 3 * (3+1) = 12
return 0xF101
3、EC(0xF101)
{0:6}
y -> 6
this.x *= (++x)+y;
<=> this.x = (this.x) * ((++x)+y);
-> 5 * (13+6) = 95
console.log(x);
-> 134、EC(0xF101)
this -> window
this.x *= (++x)+y;
-> 13 * ((13+1) + 4) = 234
console.log(x);
-> 2345、结果
测试答案正确
在计算的时候,注意
成员访问
(即.
)的level是19,以及A += B + C
、A *= B + C
都是A = A+(B+C)
、A = A*(B+C)
scopeChain
-> <AO(FN1),VO(G)>
-> 左边这个值表明了当前作用域,而右边这值表明了上一级作用域是谁 -> VO(G)
其实应该是函数(假如函数是fn
)创建时声明的作用域变量fn[[scope]]
,而在这里我们直接把最终值 VO(G)
给写上去了AO(fn)
才是fn
自己的作用域,而不是VO(G)
」 -> 简单来说,就是函数执行的那个环境才是自己的作用域 -> 虽然这样理解对代码最终的执行结果没错,但真正的作用域是指自己所在创建的那个区域呀!而EC才是函数代码执行的环境 -> 环境和作用域是有区别的…… -> 总之,想象一下你是个函数,你在家里呆着,整个家的VO(G)
就是你的作用域,而你自己执行的那个身体环境就是EC
fn1
)里边创建的函数(fn2
),意味着该fn2
与fn1
是有关系的,然后fn2
被全局某个变量(如f
)所引用,那么这意味着 fn2
是有意义的,所以fn1
执行完毕后这整个EC(fn1)
是不能被销毁的,而是压缩到ECStack
的底部……唯有这样,f
才能正常访问fn2
所指向的那个heapscopeChain
可以看出 -> 函数在哪里创建,那么这个函数体里边的上一级作用域就是谁,如函数B在函数A的肚子里创建,那么 B在执行时,其scopeChain -> <AO(B),AO(A)>
同学别费劲了,不同的编译器处理结果不同,谁在实际项目中这样写我要对他竖中指
翻译成代码:
x++
var t = x
x = x+1
return t
++x
return (x = x+1)
➹:为什么在 C 语言中,i=1;i=(++i)+(++i)+(++i)+(++i)
; 得到 i 的结果是 15 而不是 14 ? - 知乎