javascript - 从 JS 中的两个(或更多)内置对象(Map、EventTarget)继承
问题描述
我不是 JS 中的菜鸟,我知道从技术上讲没有正确的方法可以从多个类继承。所以我的问题很简单
有什么想法可以创建一个类或只是一个对象,它继承自 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
可以以某种方式在这里提供帮助
解决方案
您可以创建一个函数,该函数创建基类的私有实例,并返回一个代理,该代理将属性检索分配给这些对象之一。可以将基类传递给构造函数以保持其通用性:
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
传递给该函数的任何基类。
推荐阅读
- javascript - JSON.stringify 无法正常工作,为 json 的键提供了额外的“”
- c - 在 linux 中与没有微控制器的 I2C 设备通信
- java - ORDER BY 子句失败
- javascript - Mongoose Docs - 手动填充字段
- python - discord.py 消息被多次发送,每次增加 1
- java - Spring Webflux - 具有继承的 Webclient 请求正文
- php - 复杂多维数组
- c - 为什么当我尝试打印 % 符号时转义字符不起作用?
- asp.net-mvc - 从 RESTful Web 服务下载图像并在 razor 中使用 asp.net MVC 显示
- elixir - 迭代 Elixir 中的嵌套列表