[JavaScript] 如何改变getter方法中this的指向

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

你可能感兴趣的:([JavaScript] 如何改变getter方法中this的指向)