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()
