evo*_*box 0 javascript class composition mixins ecmascript-6
比方说,我有一个Thing,我想既类Hideable和Openable.
使用类似于Douglas Crockford通过合成创建对象的方法,我已经能够从多个类"继承".
这种方法不适用于访问器(getter/setter).
我需要使用类,因为它是一个要求.我也发现我在类之间复制功能,但我不希望它们从基类继承.
有任何想法吗?
到目前为止我所取得的进展如下:
class Openable {
constructor(isOpen = false) {
this._isOpen = isOpen;
}
get isOpen() {
return this._isOpen + ' is stupid.';
}
set isOpen(value) {
this._isOpen = value;
}
}
class Hideable {
constructor(isHidden = false) {
this._isHidden = isHidden;
}
get isHidden() {
return this._isHidden + ' is stupid.';
}
set isHidden(value) {
this._isHidden = value;
}
}
class Thing {
constructor(config) {
let { isOpen, isHidden } = config;
let openable = new Openable(isOpen);
this.isOpen = openable.isOpen;
let hideable = new Hideable(isHidden);
this.isHidden = openable.isHidden;
}
}
let thing = new Thing({
isOpen: true,
isHidden: false
});Run Code Online (Sandbox Code Playgroud)
因为isOpen并且isHidden是访问者,您不能只抓取它们的副本,您必须在需要时访问它们.
不过,你可以创建自己的 isOpen,isHidden使用底层的:
let openable = new Openable(isOpen);
Object.defineProperty(this, "isOpen", {
get: () => openable.isOpen,
set: value => {
openable.isOpen = value;
}
});
let hideable = new Hideable(isHidden);
Object.defineProperty(this, "isHidden", {
get: () => hideable.isHidden,
set: value => {
hideable.isHidden = value;
}
});
Run Code Online (Sandbox Code Playgroud)
当然,如果你经常这样做,你需要有一个工作函数来设置它而不是一直重新输入它:
function wrapProperty(dest, src, name) {
Object.defineProperty(dest, name, {
get: () => src[name],
set: value => { src[name] = value; }
});
}
Run Code Online (Sandbox Code Playgroud)
(或者通过抓取属性描述符并更新它来实现)
然后:
wrapProperty(this, openable, "isOpen");
wrapProperty(this, hideable, "isHidden");
Run Code Online (Sandbox Code Playgroud)
我会质疑你必须使用的class要求Openable和Hideable.他们看起来更像是我的混合物.