我不是JS中的Noob,我知道从技术上讲,从多个类继承没有正确的方法。所以我的问题很简单
有没有什么想法,我可以创建一个类,或仅仅是一个对象,作为它从JS Native object中的两个版本继承而来。尤其是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
可以在这方面有所帮助
发布于 2019-03-30 22:20:47
您可以创建一个函数,该函数创建基类的私有实例,并返回一个代理,该代理将属性检索分派到其中一个对象。基类可以传递给构造函数以保持其泛型:
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
操作。
发布于 2019-03-30 21:21:24
现在,对于其他寻求解决这个问题的人,我提出了这个解决方案
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);
https://stackoverflow.com/questions/55431060
复制相似问题