Я изучаю код потока NodeJS и этот пример из этой статьи Streams :
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, и пример кода объединяет два объекта вместе.
Поэтому я считаю, что объект Readable
после вызова Stream.call(this)
имеет все функции Stream и значения полей.
Это правильно?
Я предполагаю, что именно так Javascript выполнял функции, подобные наследованию, но без наследования. Я думаю, что это действительно эквивалентно объединению нескольких объектов Javascript.
Итак, чтобы подтвердить свое понимание, я написал пример кода JSFiddle , который показывает три функции fun1, fun2 и fun3 и MyMultiObj вызывает их, как показано ниже:
function MyMultiObj() {
fun1.call(this);
fun2.call(this);
fun3.call(this);
}
let myMulti = new MyMultiObj();
В этом коде объект myMulti
обладает всеми функциями и полями 4 функций MyMultiObj, fun1, fun2 и fun3.
Я также заметил, что функции, определенные с помощью прототипирования (например, fun2.prototype.really2()
, не были объединены / недоступны, что имеет смысл, потому что этот подход НЕ использует прототипирование).
Я думаю, что это довольно круто, и я вижу преимущества, но хочу
(a) убедитесь, что мое понимание верно, ... объект Readable
после вызова Stream.call(this)
имеет все функции Stream и значения полей, а
(б) выяснить, почему это делается вместо типичного прототипирования / наследования (если есть причина).