【发布时间】:2018-10-29 05:29:46
【问题描述】:
我正在研究这个Streams article中的NodeJS Stream代码和这个例子:
const { Readable } = require('stream');
const inStream = new Readable({
read() {}
});
inStream.push('ABCDEFGHIJKLM');
inStream.push('NOPQRSTUVWXYZ');
inStream.push(null); // No more data
inStream.pipe(process.stdout);
当我进入new Readable() 调用时,我看到如下代码:
const Stream = require('stream');
function Readable(options) {
// ...
Stream.call(this);
}
Stream.call(this) 是做什么的?我以前从未见过这样的代码。
我知道 Javascript Object.call() 方法的作用,并且通常在另一个函数中看到它。
myObj.myFunc.call(this);
我阅读了 MDN https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/call,示例代码将两个对象组合在一起。
所以我认为调用Stream.call(this) 后的Readable 对象具有所有Stream 函数和字段值。
这是正确的吗?
我猜这是 Javascript 实现类继承功能的方式,但没有继承。我认为这真的相当于合并多个 Javascript 对象。
为了证明我的理解,我写了一个JSFiddle code example,其中显示了三个函数 fun1、fun2 和 fun3,并让 MyMultiObj 调用它们,如下所示:
function MyMultiObj() {
fun1.call(this);
fun2.call(this);
fun3.call(this);
}
let myMulti = new MyMultiObj();
在此代码中,myMulti 对象具有 MyMultiObj、fun1、fun2 和 fun3 4 个函数的所有功能和字段。
我还注意到通过原型定义的函数(例如,fun2.prototype.really2() 没有合并/可用,这是有道理的,因为这种方法不使用原型)。
我觉得这很酷,而且可以看到好处,但是想
(a) 验证我的理解是否正确,...调用
Stream.call(this)后的Readable对象具有所有Stream 函数和字段值,并且(b) 找出为什么这样做而不是典型的原型设计/继承(如果有原因的话)。
【问题讨论】:
-
它正在调用父构造函数。
Readable继承自Stream,因此它将其原型设置为从Stream的原型继承,并进行此调用以初始化自身。对于 ES6 类,它看起来像class Readable extends Stream { constructor() { super(); } }(尽管如果它只调用super(),你可以省略constructor())。 -
@Ry,我认为它确实不是父构造函数,因为它没有使用
class extends或Stream.prototype.func2,这是正确的。我确实同意它在概念上与您描述的相似。就是说把这个函数附加到我自己(我的this)。 -
不,它实际上只是常规继承,以最令人困惑的方式编写,因为文件滥用了提升。这里是原型设置的地方:github.com/nodejs/node/blob/…
标签: javascript node.js node-streams