这个问题在这里已有答案:
在当前使用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中定义。
这里有什么收获?
当您尝试检索属性,并且该属性不在实例上时,引擎将查找链中第一个对象的原型链,该对象具有相关属性的属性描述符。当找到所述描述符时,如果它具有getter,则调用该getter。否则,如果没有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')
上没有找到吸气剂(或纯值)。
如果你有一个getter,并且你希望能够设置相同的属性,那么setter必须与getter在同一个对象上,反之亦然。