Getter / Setter 和原型链
Getter / Setter and Prototype Chain
在当前使用 ES6 class 语法和 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.__value确实是2),但是getter似乎不存在,尽管它仍然在A.prototype中定义。
这里有什么问题?
当您尝试检索 属性,而 属性 不在实例上时,引擎将首先查找 [=38] 的原型链=] 链中的对象,它有一个 属性 描述符用于 属性 问题。当找到所述描述符时,如果它有一个 getter,则调用 getter。否则,如果没有 getter,它将检索 属性 的普通值,如果有
在第二种情况下,属性 描述符在 B.prototype
上。但是 B.prototype
没有 value
的 getter (B.prototype
也没有 value
的普通值)!所以,undefined
是 returned.
如果 B.prototype
有 getter 用于 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;
但它没有。引擎不会继续在原型链中向上寻找 getter - 相反,它会停止并 return undefined
,因为没有 getter(或纯值) 在原型链中的第一个对象上找到 hasOwnProperty('value')
.
如果您有一个 getter,并且您希望能够设置相同的 属性,则 setter 必须与 getter 在同一对象上,反之亦然。
在当前使用 ES6 class 语法和 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.__value确实是2),但是getter似乎不存在,尽管它仍然在A.prototype中定义。
这里有什么问题?
当您尝试检索 属性,而 属性 不在实例上时,引擎将首先查找 [=38] 的原型链=] 链中的对象,它有一个 属性 描述符用于 属性 问题。当找到所述描述符时,如果它有一个 getter,则调用 getter。否则,如果没有 getter,它将检索 属性 的普通值,如果有
在第二种情况下,属性 描述符在 B.prototype
上。但是 B.prototype
没有 value
的 getter (B.prototype
也没有 value
的普通值)!所以,undefined
是 returned.
如果 B.prototype
有 getter 用于 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;
但它没有。引擎不会继续在原型链中向上寻找 getter - 相反,它会停止并 return undefined
,因为没有 getter(或纯值) 在原型链中的第一个对象上找到 hasOwnProperty('value')
.
如果您有一个 getter,并且您希望能够设置相同的 属性,则 setter 必须与 getter 在同一对象上,反之亦然。