问题描述
当前版本的JavaScript将EventTarget实现为类而不是接口,因此您可以使用所有期望的方法创建EventTarget的实例.
我试图复制/粘贴 EventTarget示例在控制台中(在Chrome和Firefox上),但是当我检查myEventTarget对象(作为名为MyEventTarget的EventTarget的子类构建)时,控制台会说myEventTarget是EventTarget,而不是MyEventTarget.
这是代码
//this is the MDN example
class MyEventTarget extends EventTarget {
constructor(mySecret) {
super();
this._secret = mySecret;
}
get secret() { return this._secret; }
};
let myEventTarget = new MyEventTarget(5);
let value = myEventTarget.secret; // == 5
myEventTarget.addEventListener("foo", function(e) {
this._secret = e.detail;
});
let event = new CustomEvent("foo", { detail: 7 });
myEventTarget.dispatchEvent(event);
let newValue = myEventTarget.secret; // == 7
// the following is the code I have added
// everything seems to work as usual, ie
console.log(myEventTarget instanceof MyEventTarget)
// the console says that is true
// but if I try to print the instance...
console.log(myEventTarget)
// EventTarget { _secret: 7 }
为什么控制台说myEventTarget只是一个EventTarget?
我发现这很不常见,因为如果键入以下代码,控制台会说myEventTarget实际上是MyEventTarget实例
class MyEventTarget extends class SomeOtherClass{} {
constructor(mySecret) {
super();
this._secret = mySecret;
}
get secret() { return this._secret; }
};
let myEventTarget = new MyEventTarget(5);
console.log(myEventTarget instanceof MyEventTarget)
// the console diligently says that is true
// and if I try to print the instance...
console.log(myEventTarget)
// ...the console correcly says
// MyEventTarget { _secret: 5 }
因此,如果我将EventTarget用作超类,则实例会丢失其构造函数名称?我知道这没什么大不了的,我认为打印类名称仅用于调试目的,但这是有原因的吗?
之所以会发生这种情况,是因为EventTarget
会覆盖 Symbol.toStringTag
,您将继承此行为.您可以将其覆盖为所需的任何内容.
class MyEventTarget extends EventTarget {
constructor(mySecret) {
super();
this._secret = mySecret;
}
get secret() { return this._secret; }
get [Symbol.toStringTag]() {
return this.constructor.name
}
};
let myEventTarget = new MyEventTarget(5);
let value = myEventTarget.secret; // == 5
myEventTarget.addEventListener("foo", function(e) {
this._secret = e.detail;
});
let event = new CustomEvent("foo", { detail: 7 });
myEventTarget.dispatchEvent(event);
let newValue = myEventTarget.secret; // == 7
// the following is the code I have added
// everything seems to work as usual, ie
console.log(myEventTarget instanceof MyEventTarget)
// the console says that is true
// but if I try to print the instance...
console.log(myEventTarget)
// MyEventTarget { _secret: 7 }
console.log(Object.prototype.toString.call(myEventTarget))
// [object MyEventTarget]
The current version of JavaScript implements EventTarget as a class instead of an interface, so you can create an instance of EventTarget with all the expected methods.
I tried to copy/paste the EventTarget example in the console (on both Chrome and Firefox) but when I inspect the myEventTarget object (that is build as a subclass of EventTarget named MyEventTarget), the console says that myEventTarget is an EventTarget, not a MyEventTarget.
This is the code
//this is the MDN example
class MyEventTarget extends EventTarget {
constructor(mySecret) {
super();
this._secret = mySecret;
}
get secret() { return this._secret; }
};
let myEventTarget = new MyEventTarget(5);
let value = myEventTarget.secret; // == 5
myEventTarget.addEventListener("foo", function(e) {
this._secret = e.detail;
});
let event = new CustomEvent("foo", { detail: 7 });
myEventTarget.dispatchEvent(event);
let newValue = myEventTarget.secret; // == 7
// the following is the code I have added
// everything seems to work as usual, ie
console.log(myEventTarget instanceof MyEventTarget)
// the console says that is true
// but if I try to print the instance...
console.log(myEventTarget)
// EventTarget { _secret: 7 }
Why the console says that myEventTarget is just an EventTarget?
I found this thing quite uncommon because if I type the following code the console says that myEventTarget is actually a MyEventTarget instance
class MyEventTarget extends class SomeOtherClass{} {
constructor(mySecret) {
super();
this._secret = mySecret;
}
get secret() { return this._secret; }
};
let myEventTarget = new MyEventTarget(5);
console.log(myEventTarget instanceof MyEventTarget)
// the console diligently says that is true
// and if I try to print the instance...
console.log(myEventTarget)
// ...the console correcly says
// MyEventTarget { _secret: 5 }
so if I use EventTarget as superclass, the instances lose their constructor name?I understand that is not a big deal, I think that print class names is just for debugging purpose but there is a reason for this?
This happens because EventTarget
overrides Symbol.toStringTag
and you inherit this behaviour. You can override it to be whatever you want.
class MyEventTarget extends EventTarget {
constructor(mySecret) {
super();
this._secret = mySecret;
}
get secret() { return this._secret; }
get [Symbol.toStringTag]() {
return this.constructor.name
}
};
let myEventTarget = new MyEventTarget(5);
let value = myEventTarget.secret; // == 5
myEventTarget.addEventListener("foo", function(e) {
this._secret = e.detail;
});
let event = new CustomEvent("foo", { detail: 7 });
myEventTarget.dispatchEvent(event);
let newValue = myEventTarget.secret; // == 7
// the following is the code I have added
// everything seems to work as usual, ie
console.log(myEventTarget instanceof MyEventTarget)
// the console says that is true
// but if I try to print the instance...
console.log(myEventTarget)
// MyEventTarget { _secret: 7 }
console.log(Object.prototype.toString.call(myEventTarget))
// [object MyEventTarget]
这篇关于为什么EventTarget子类实例会丢失名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!