You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

eventemitter3创建的对象constructor属性为undefined的问题咨询

为什么eventemitter3实例的constructor属性是undefined?

这个问题其实是eventemitter3的设计特性导致的,我来给你拆解清楚:

首先,MDN那句“所有对象都具备constructor属性”其实有个容易被忽略的前提——这里的对象指的是默认继承自Object.prototype的普通对象。而eventemitter3为了性能优化,特意修改了它的原型链结构:

eventemitter3的作者将EventEmitter.prototype的原型设置成了null(而不是默认的Object.prototype),并且没有在这个原型对象上显式定义constructor属性。这样一来,当你创建一个事件发射器实例(比如你的temp1)时,它的原型链是:
temp1 → EventEmitter.prototype → null

而普通JS对象的原型链是:
普通对象 → Object.prototype → null

因为EventEmitter.prototype本身没有constructor属性,也没法从上层的null继承到,所以当你访问temp1.constructor时,自然就返回undefined了。

验证结论的小技巧

你可以在控制台里跑这几行代码确认:

const EventEmitter = require('eventemitter3');
const temp1 = new EventEmitter();

// 查看temp1的原型对象
console.log(Object.getPrototypeOf(temp1));
// 检查这个原型对象自身有没有constructor属性
console.log(Object.hasOwnProperty.call(Object.getPrototypeOf(temp1), 'constructor')); // 会返回false
// 查看原型对象的原型是不是null
console.log(Object.getPrototypeOf(Object.getPrototypeOf(temp1))); // 会返回null

怎么获取构造函数?

如果你确实需要拿到实例的构造函数,有两种简单的方式:

  • 直接使用EventEmitter本身(毕竟你就是用它创建的实例)
  • 手动给EventEmitter.prototype添加constructor属性:
EventEmitter.prototype.constructor = EventEmitter;
// 之后再访问temp1.constructor就会得到EventEmitter了

补充一下为什么eventemitter3要这么做

这么设计主要是为了性能:当遍历_events对象里的事件时,不用额外做hasOwnProperty检查(因为_events也是用Object.create(null)创建的,没有原型链属性),同时原型链更短,属性查找更快。

内容的提问来源于stack exchange,提问作者River Tam

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:15:12