- 找到真正调用的函数
- 真正函数调用时候,看()左边的东西,找到左边东西所在的对象,这个时候所在的对象就是this。
var num = 10
function fn(){
console.log(this.num);
}
let obj={
num:5,
method:function(fn){
fn();
arguments[0]();
}
}
obj.method(fn,1)//10 undefined
在调用obj.method的时候,其实真正调用的是fn(),左边的部分为fn,fn的Reference为
{
base:window,
name:'fn',
strict:false
},
所以this的值就是GetBase(ref)->base value->window,所以输出num
调用arguments0,看arguments[0],arguments[0]的Reference
{
base:arguments,
name:'arguments[0]',
strict:false
}
所以this的值就是GetBase(ref)->base value->arguments,arguments中不存在num,所以为undefined
如果修改成为arguments.num = 1再执行 arguments0则输出1
关键在于判断 MemberExpression是否为Reference类型
- ref = MemberExpression【()左边的部分就是 MemberExpression】
- 判断ref是不是一个Reference类型
-
如果 ref 是 Reference,并且 IsPropertyReference(ref) 是 true【如果base value的值为对象就为true】, 那么 this 的值为 GetBase(ref)【GetBase返回Reference的base value】
base value的值为对象,那么this的值就是base value->也就是属性所在的对象 -
如果 ref 是 Reference,并且 base value 值是 Environment Record, 那么this的值为 ImplicitThisValue(ref)【该函数始终返回undefined】
-
如果 ref 不是 Reference,那么 this 的值为 undefined
Reference的构成
- base value,就是属性所在的对象 || EnvironmentRecord,值只可能是 undefined, an Object, a Boolean, a String, a Number, or an environment record中的一种
- referenced name,属性的名称
- strict reference,是否在严格模式下
网友评论