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

标签 javascript ecmascript-6

当前版本的 JavaScript 将 EventTarget 实现为类而不是接口(interface),因此您可以使用所有预期的方法创建 EventTarget 的实例。

我尝试复制/粘贴 EventTarget example在控制台中(在 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 作为父类(super class),实例会丢失其构造函数名称吗? 我知道这没什么大不了的,我认为打印类名只是为了调试目的,但这是有原因的吗?

最佳答案

发生这种情况是因为 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]

关于javascript - 为什么 EventTarget 子类实例会丢失名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60226607/

相关文章:

javascript - 如何解析模块中命名的 ES6/ES2015 导出列表?

javascript - d3.js NVD3 手动触发工具提示

javascript - 打印模板文字中的箭头函数

javascript - 如何使用 RegExp 多次匹配重叠模式

javascript - jQuery:重构为函数

javascript - ES6 Module Loader中简单import语句和System.import的区别

javascript - `eval` 调用上下文正在评估形参初始值设定项时声明实例化

javascript - 了解 React Native 程序流程 - 循环

javascript - 如何防止浏览器打开启动 Strapi

javascript - 'This' 在构造函数和继承的构造函数中不相同