有人能以通俗易懂的语言解释一下util.inherits是做什么的吗?

8

http://nodejs.org/docs/latest/api/util.html#util_util_inherits_constructor_superconstructor

在上述文档中,他们谈到了 util.inherits,它需要两个构造函数。我正在努力理解他们提供的代码示例。我知道什么是 Stream,知道什么是 EventEmitter,并且理解为什么要让流从 EventEmitter 继承,但是我真的很困惑他们是如何做到的。 util.inherits 到底是做什么的?为什么要创建一个调用 events.EventEmitter.call(this); 的新构造函数?这种奇怪的做法与只创建一个 EventEmitter 实例并将其设置为 MyStream.prototype 有什么区别?
以下是该文章的代码示例:
var util = require("util");
var events = require("events");

function MyStream() {
    events.EventEmitter.call(this);
}

util.inherits(MyStream, events.EventEmitter);

MyStream.prototype.write = function(data) {
    this.emit("data", data);
}

var stream = new MyStream();

console.log(stream instanceof events.EventEmitter); // true
console.log(MyStream.super_ === events.EventEmitter); // true

stream.on("data", function(data) {
    console.log('Received data: "' + data + '"');
})
stream.write("It works!"); // Received data: "It works!"
2个回答

8
var util = require('util');

function Person() {
    this.firstname = 'John';
    this.lastname = 'Doe';
}

Person.prototype.greet = function() {
    console.log('Hello ' + this.firstname + ' ' + this.lastname);
}

function Policeman() {
    Person.call(this);
    this.badgenumber = '1234';
}

util.inherits(Policeman, Person);
var officer = new Policeman();
officer.greet();

6
你可以在这里找到util.inherits的实现:这里
exports.inherits = function(ctor, superCtor) {
  ctor.super_ = superCtor;
  ctor.prototype = Object.create(superCtor.prototype, {
    constructor: {
      value: ctor,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });
};

本质上,它正在执行您所描述的操作(创建events.EventEmitter.prototype的实例并将其设置为MyStream的原型),同时将events.EventEmitter附加到MyStream.super_

events.EventEmitter.call(this);调用events.EventEmitter构造函数,以便在创建新的MyStream时执行该函数。这相当于在其他语言(如Java)中调用super()


我现在对util.inherits有了清晰的理解,谢谢。但我仍然不完全理解调用superConstructor的原因。将原型设置为superConstructor的新实例不足以吗? - Chev
@AlexFord:设置原型只是意味着MyStream的实例将继承EventEmitter.prototype中的函数。当调用new MyStream()时,EventEmitter构造函数不会自动调用。 - go-oleg
嗯,这似乎与文本所说的不符。“constructor原型将被设置为从superConstructor创建的新对象。”这是否意味着MyStream的原型设置为EventEmitter的实例,而不仅仅是EventEmitter.prototype?如果是这样,这是否也意味着MyStream将继承构造函数EventEmitter在创建实例时添加到该实例中的任何内容?我不是说你错了,只是想要理解 :) - Chev
我觉得我正陷入困境,试图弄清楚你发布的 inherits 函数代码中的 Object.create 到底在做什么。我确实认为你是对的,文档中的内容是错误的。只是我不完全明白为什么会这样做。也许我不完全理解 Object.create 的用处和它正在做什么?看起来它正在获取 EventEmitter 的原型并向其中添加一个 constructor 属性(我不确定它是干什么用的),然后将其分配给 MyStream.prototype。所以它只是与 EventEmitter 相同的原型,带有一个 constructor 属性? - Chev
我猜在MyStream的构造函数中调用EventEmitter构造函数对this是有意义的。我想这里有两件事让我感到困惑:1.为什么不创建一个新的EventEmitter实例并将其分配给MyStream.prototype?2.util.inherits为新原型添加了一个constructor属性,它是做什么用的? - Chev
请将以下与编程有关的内容从英语翻译成中文。仅返回已翻译的文本:请参见此示例https://github.com/dacosta-rafael/node-util.inherits/blob/master/app2.js - daily-learner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接