在当前使用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中定义了该吸气剂,但它似乎不存在。
这里有什么收获?
答案 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')
。
如果您有一个吸气剂,并且希望能够设置相同的属性,则该吸气剂必须与该吸气剂在同一对象上,反之亦然。