javascript - Getter/Setter 和原型(prototype)链

标签 javascript prototype getter-setter es6-class

<分区>

在当前使用 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

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

这里有什么问题?

最佳答案

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

在第二种情况下,属性描述符在B.prototype上。但是 B.prototype 没有 value 的 getter(B.prototype 也没有 value 的普通值>)!因此,undefined 被返回。

如果 B.prototype 有一个 value 的 getter,它将被调用:

'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;

但它没有。引擎不会继续在原型(prototype)链中向上寻找 getter——相反,它会停止并返回 undefined,因为在原型(prototype)链中的第一个对象上没有找到 getter(或普通值) hasOwnProperty('value') 的原型(prototype)链。

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

关于javascript - Getter/Setter 和原型(prototype)链,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55158334/

相关文章:

javascript - 自定义组件的关注点分离?

javascript - 使用 Firebase,firebase.auth().currentUser 是 null 值,即使它正在被记录

javascript - 使用私有(private)/ protected /公共(public)字段和方法扩展类

javascript - 复制 javascript 原型(prototype)实例?

Grails域类 transient 集合属性 setter 问题

ios - 覆盖 UITextField getter-setter

ruby-on-rails - Rails 多态关联 : getter and setter methods

Javascript函数构造

javascript - 将事件标题类添加到当前标题

javascript - React 组件中的不同区域