为什么EventTarget子类实例会丢失名称

为什么EventTarget子类实例会丢失名称

本文介绍了为什么EventTarget子类实例会丢失名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前版本的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子类实例会丢失名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 09:49