Javascript,扩展 ES6 类 setter 将继承 getter
Posted
技术标签:
【中文标题】Javascript,扩展 ES6 类 setter 将继承 getter【英文标题】:Javascript, extending ES6 class setter will inheriting getter 【发布时间】:2019-05-04 05:06:43 【问题描述】:在 javascript 中,带有以下插图代码:
class Base
constructor() this._val = 1
get val() return this._val
class Xtnd extends Base
set val(v) this._val = v
let x = new Xtnd();
x.val = 5;
console.log(x.val); // prints 'undefined'
实例x
不会从Base
类继承get val()...
。事实上,Javascript 将在 setter 存在的情况下不存在 getter 视为未定义。
我有一种情况,我有很多类都有完全相同的 getter 集,但 setter 是唯一的。目前,我只是在每个类中复制 getter,但我正在重构并希望消除冗余代码。
有没有办法告诉 JS 让 getter 远离基类,或者有没有人有一个优雅的解决方案来解决这个问题?
【问题讨论】:
供以后参考,这个问题与redundancy标签无关,它指的是故意复制代码以使关键部分更健壮。我很确定您打算使用boilerplate,它指的是看似不必要的代码重复。 "我有很多类都具有完全相同的 getter 集但唯一的 setter。" - 你真的需要继承吗?如果您只想避免重复,那么 JS 还有很多其他共享代码的方式。 "有没有办法告诉 JS 将 getter 保留在基类中" - No, it's by design. 【参考方案1】:这个限制是由于 JavaScript 如何在后台处理属性访问器。在 ECMAScript 5 中,您最终会得到一个原型链,其中包含一个用于 val
的 property descriptor 以及一个由您的类定义的 get
方法,以及一个未定义的 set
方法。
在您的Xtnd
类中,您有另一个val
的属性描述符,它隐藏了基类val
的整个属性描述符,其中包含一个由该类定义的set
方法和一个get
方法,即未定义。
为了将 getter 转发到基类实现,不幸的是,您需要在每个子类中使用一些样板,但您至少不必复制实现本身:
class Base
constructor() this._val = 1
get val() return this._val
class Xtnd extends Base
get val() return super.val
set val(v) this._val = v
let x = new Xtnd();
x.val = 5;
console.log(x.val); // prints '5'
【讨论】:
这个半令人满意的解决方案有效。谢谢。 ...但对更优雅的解决方案抱有希望。 @codechimp 你在使用转译器吗?如果是这样,我可以使用类装饰器和/或方法装饰器添加另一个解决方案,将属性访问器转发到基类。这听起来像是对您有益的事情吗? Transpilier 是我想到的一种解决方案,但我拒绝使用它。我理解它的价值,但我想保留这个代码库纯香草 JS。以上是关于Javascript,扩展 ES6 类 setter 将继承 getter的主要内容,如果未能解决你的问题,请参考以下文章