我不是JS的Noob,而且我知道从技术上讲,没有正确的方法可以从多个类继承。所以我的问题很简单
有什么主意,我该如何创建一个类或只是一个从JS Native对象的两个内部版本继承而来的对象。特别是EventTarget
和另一个对象。
我尝试:
var map = new Map();
var eventtarget = new EventTarget();
mix = Object.create({...Map.prototype, ...EventTarget.prototype});
Object.assign(mix, et , map);
似乎不起作用,因为Map.prototype
中的方法不是可迭代的
也使用Object.assign({}, Map.prototype, ...EventTarget.prototype)
具有相同的效果。
另一种尝试:
class Base5 extends Map{
constructor(){
super();
var eventTarget = new EventTarget();
Object.assign(this,eventTarget);
}
}
Base5.prototype = Object.create(Base5.prototype)
Object.assign(Base5.prototype,EventTarget.prototype);
// that seem to work
const b5 = new Base5();
b5.set('foo','bar');
// but...
b4.addEventListener('fire', _=>_ )
// throw Uncaught TypeError: Illegal invocation at <anonymous>:1:4
此方法有效,但不通用
const wm = new WeakMap();
class Base6 extends Map{
constructor(){
super();
wm.set(this, new EventTarget() )
}
addEventListener(){
wm.get(this).addEventListener(...arguments)
}
dispatchEvent(){
wm.get(this).dispatchEvent(...arguments)
}
removeEventListener(){
wm.get(this).removeEventListener(...arguments)
}
}
const b6 = new Base6();
b6.set('foo','bar'); // Map(1) {"foo" => "bar"}
b6.addEventListener('foo', e=>console.log(e) );
b6.dispatchEvent( new Event('foo') )
那么任何人都可以采用更好的方法?
也许Reflect.construct
可以在某种程度上为您提供帮助
答案 0 :(得分:1)
您可以创建一个函数,该函数创建基类的私有实例,并返回一个代理,该代理将属性检索分配给那些对象之一。可以将基类传递给构造函数以使其保持通用:
createMix(Map, EventTarget)
几件事仍然是有问题的。一个阻塞问题是方法调用通常需要将this
设置为基础对象才能起作用。解决方法可能是返回一个绑定的方法,知道它本身可能会产生不良影响(例如,客户根本无法采用该方法并将其自身绑定到其他对象上-如果这完全有意义)。
可以肯定的是,这并不能解决所有潜在的问题,但似乎可以在非常基本的用法中起作用:
function createMix(...classes) {
const obj = {};
const instances = [obj, ...classes.map(cls => new cls)];
return new Proxy(obj, {
get(obj, prop) {
obj = instances.find(obj => prop in obj);
const val = Object(obj)[prop];
return typeof val === "function" ? val.bind(obj) : val;
},
has(obj, prop) { // Optional: if you care about the `in` operator
return instances.some(obj => prop in obj);
}
});
}
// Tiny test
const obj = createMix(Map, EventTarget);
obj.set('foo','bar');
console.log("Map contains: ", Object.fromEntries(obj));
obj.addEventListener('foo', e => console.log("Event object type: ", e.type) );
obj.dispatchEvent( new Event('foo') );
此函数返回一个容器对象,因此不会instanceof
传递给该函数的任何基类。
答案 1 :(得分:1)
@trincot show-me-a-way / inspire-me进行了更多研究,并提供了可改善其解决方案某些方面的以下解决方案:
1)对继承函数的弱绑定
2)能够使用混合类作为原型来扩展另一个自定义类。
如果您喜欢我的答案,也不要忘记竖起大拇指。
最后,简码可以扩展多个本机类,可能并不完美,因此,如果发现问题,请发表评论,但这只是一个开始,我们将来可以改进它:
MainAxisAlignment.spaceEvenly
答案 2 :(得分:0)
目前,对于寻求解决该问题的其他人,我将采用这种解决方案
const wm = new WeakMap();
function Emitter(Base) {
return class extends Base {
constructor() {
super(...arguments);
wm.set(this, new EventTarget())
}
addEventListener() {
wm.get(this).addEventListener(...arguments)
}
dispatchEvent() {
wm.get(this).dispatchEvent(...arguments)
}
removeEventListener() {
wm.get(this).removeEventListener(...arguments)
}
}
}
// how to use
const EmitterableMap = Emitter(Map);