gpt4 book ai didi

javascript - Node.js 奇怪的原型(prototype)继承

转载 作者:行者123 更新时间:2023-11-30 12:43:13 25 4
gpt4 key购买 nike

我一直在关注 Manuel Teixiera 的 Hands-On Node.js,并且在阅读 Event Emitter 一章时偶然发现了这种奇怪的行为。

作者建议的代码包含如下内容:

var EventEmitter = require("events").EventEmitter;
var util = require ("util");

var MyClass = function() {};
util.inherits(MyClass, EventEmitter);
var instance = new MyClass();
instance.on("custom", function() {
console.log("Holo");
});

instance.emit("custom");*/

输出“Holo”就好了。但是,我也阅读了文档和 SO questions关于如何使用 new Function(); 的主题是一种反模式,它与 javascript 对原型(prototype)继承的预期用途背道而驰。 This article by David Walsh说明了在 js 上强制经典继承与使用其功能进行原型(prototype)继承之间的区别。

所以,我尝试通过重写来修改我的代码:

var EventEmitter = require("events").EventEmitter;
var clock = {};
util.inherits(clock, EventEmitter);
clock.on("custom", function(){
console.log("Holo");
});
clock.emit("custom");

我收到一条错误消息,提示 TypeError: Object object has no method 'on'。我不明白为什么会这样,因为我使用 util.inherit() 助手创建了时钟对象。使用 var clock = Object.create(EventEmitter) 的相同代码也不起作用。

我可以让代码工作的唯一实例是:

var EventEmitter = require("events").EventEmitter;
var util = require("util");
var clock = {};
util.inherits(clock, EventEmitter);
clock.prototype.on("custom", function(){
console.log("Holo");
});
clock.emit = function(){
clock.prototype.emit("custom");
}
clock.emit();

这会很好地输出“Holo”。问题是,我不明白为什么我需要访问原型(prototype)来设置事件监听器或发出事件,据推测,我让 clock 变量将它的方法委托(delegate)给 EventEmitter 对象,因此它们在没有原型(prototype)符号的情况下应该可以正常工作。

你能帮帮我吗?

最佳答案

根据node.js docs :

util.inherits(constructor, superConstructor)

Inherit the prototype methods from one constructor into another. The prototype of constructor will be set to a new object created from superConstructor.

您正在传递一个对象,其中 util.inherits 旨在期待一个构造函数。 util.inherits 通过重新定义构造函数的 prototype 属性进行操作,该属性对由该构造函数构造的实例具有原型(prototype)链含义。您传入了一个对象,而不是构造函数,该对象的 prototype 属性已更改。这对任何事情都没有影响:您刚刚在名为“prototype”的对象上创建了一个属性,这与您在名为 foobar 的对象上创建了一个属性一样特别

有一种思想流派避免使用 new(支持调用 Object.create 的工厂函数——参见 Is JavaScript's "new" keyword considered harmful? 上的讨论),但是显然,实现 util.inherits 的 API 设计者不同意这种观点。

但是,您尝试的 Object.create(EventEmitter) 确实不正确,因为 Object.create 需要原型(prototype)对象,而不是构造函数。相反,您会执行 Object.create(EventEmitter.prototype)。这与调用 new EventEmitter() 相同,只是 Object.create 变体不调用 EventEmitter 构造函数。

关于javascript - Node.js 奇怪的原型(prototype)继承,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23616474/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com