吸气/塞特和原型链

时间:2019-03-14 08:52:44

标签: 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中定义)有效。

现在考虑以下演示,在该演示中,我仅将二传手从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 .__ value的确为2),但是尽管仍在A.prototype中定义了该吸气剂,但它似乎不存在。

这里有什么收获?

1 个答案:

答案 0 :(得分:4)

当您尝试检索属性,而该属性不在实例中时,引擎将在链中具有属性描述符的 first 对象中查找原型链。有问题的财产。当找到所述描述符时,如果它具有吸气剂,则该吸气剂被调用。否则,如果没有getter,它将获取该属性的纯值(如果有)。

在第二种情况下,属性描述符位于B.prototype上。但是B.prototype没有value的吸气剂(B.prototype也没有value的简单值)!因此,将返回undefined

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

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

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