1. 普通方法中的this
指向
let a = {
b() {
return this;
}
};
console.log(a.b() === a); //true
let c = {
d: a.b
};
console.log(c.d() !== a); //true
console.log(c.d() === c); //true
console.log(c.d.call(a) === a); //true
2. getter方法中的this
指向
let a = {
get b() {
return this;
}
};
console.log(a.b === a); //true
let c = {
d: a.b
};
console.log(c.d === a); //true
因为c.d
的值,在c
初始化的时候就确定了(是a
调用getter方法b
返回的值。
3. 改变getter方法中this
的指向
因为b
实际上是一个方法,每次访问b
属性的时候,都进行了方法调用,
而方法实际上是类型为函数的属性。
利用这两点,我们可以构建一个对象x
,以a
为原型,x.__proto__===a
。
这个新对象是没有b
方法(或属性)的。
访问x.b
如果找不到的话,根据原型继承,会自动到x.__proto__
中查找b
属性,即在a
对象上查找b
属性。
因为调用方式是x.b
,根据简记法b
前面是x
,所以这样调用b
方法中的this
就会指向x
了。(“简记法”可以查EcmaScript规范验证,此处略。
let a = {
get b() {
return this;
}
};
console.log(a.b === a); //true
let c = Object.create(a);
console.log(c.b !== a); //true
console.log(c.b === c); //true
4. 让getter方法中的this
指向任意对象
let a = {
get b() {
return this;
}
};
console.log(a.b === a); //true
let c = {};
Reflect.setPrototypeOf(c, a);
console.log(c.b === c); //true
其中,Reflect.setPrototypeOf(c, a)
的作用相当于设置c.__proto__
为a
。
注:
通过Reflect.getOwnPropertyDescriptor(a, 'b').get
可以得到getter方法。
参考
getter - MDN
Object.create - MDN
Reflect.setPrototypeOf()
Reflect.getOwnPropertyDescriptor()