Getter / Setter和原型链[重复]

问题描述 投票:8回答:1

这个问题在这里已有答案:

在当前使用ES6类语法和get / set语法的JavaScript项目中,我偶然发现了一个我无法解释的行为。

首先,提取的演示按预期工作:

class A {
    constructor() {
        this.__value = null;
    }

    get value() {
        return this.__value;
    }

    set value(value) {
        this.__value = value;
    }
}

class B extends A { }

let b = new B();
b.value = 2;
console.log(b.value); // output: 2

设置和获取b.value(在A.prototype中定义)有效。

现在考虑下面的演示,我将setter从A移动到B:

class A {
    constructor() {
        this.__value = null;
    }

    get value() {
        return this.__value;
    }
}

class B extends A {
    set value(value) {
        this.__value = value;
    }
}

let b = new B();
b.value = 2;          // b.__value is 2
console.log(b.value); // output: undefined

设置值有效(因为b .__值确实为2),但是getter似乎并不存在,尽管它仍然在A.prototype中定义。

这里有什么收获?

javascript prototype getter-setter es6-class
1个回答
4
投票

当您尝试检索属性,并且该属性不在实例上时,引擎将查找链中第一个对象的原型链,该对象具有相关属性的属性描述符。当找到所述描述符时,如果它具有getter,则调用该getter。否则,如果没有getter,它将检索该属性的普通值(如果有)。

在第二种情况下,属性描述符在B.prototype上。但B.prototype没有value的吸气剂(B.prototype也没有value的普通价值)!所以,undefined被退回。

如果B.prototypevalue的吸气剂,它将被调用:

'use strict';

class A {
    constructor() {
        this.__value = null;
    }

    get value() {
        return this.__value;
    }
}

class B extends A {
    set value(value) {
        this.__value = value;
    }
    get value() {
        console.log('trying to get value');
    }
}

let b = new B();
b.value = 2;
b.value;

但它没有一个。引擎不会继续在原型链中向上寻找吸气剂 - 相反,它只会停止并返回undefined,因为在原型链中的第一个物体hasOwnProperty('value')上没有找到吸气剂(或纯值)。

如果你有一个getter,并且你希望能够设置相同的属性,那么setter必须与getter在同一个对象上,反之亦然。

© www.soinside.com 2019 - 2024. All rights reserved.