Browse Source

doc: discourage use of util.inherits

util.inherits breaks the prototype chain. A fix does not seem
useful, since ES6 extends provides language level support for the
same functionality.

This commit starts fasing out mentions of the method.

Fixes: https://github.com/nodejs/node/issues/6512
Fixes: https://github.com/nodejs/node/issues/4179

PR-URL: https://github.com/nodejs/node/pull/6514
Reviewed-By: James Snell <jasnell@gmail.com>
Reviewed-By: Michaël Zasso <mic.besace@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
process-exit-stdio-flushing
Robert Jefe Lindstaedt 9 years ago
parent
commit
9daf4a2937
  1. 21
      doc/api/events.md
  2. 79
      doc/api/stream.md
  3. 5
      doc/api/util.md

21
doc/api/events.md

@ -27,27 +27,6 @@ The following example shows a simple `EventEmitter` instance with a single
listener. The `eventEmitter.on()` method is used to register listeners, while
the `eventEmitter.emit()` method is used to trigger the event.
```js
const EventEmitter = require('events');
const util = require('util');
function MyEmitter() {
EventEmitter.call(this);
}
util.inherits(MyEmitter, EventEmitter);
const myEmitter = new MyEmitter();
myEmitter.on('event', () => {
console.log('an event occurred!');
});
myEmitter.emit('event');
```
Any object can become an `EventEmitter` through inheritance. The example above
uses the traditional Node.js style prototypical inheritance using
the `util.inherits()` method. It is, however, possible to use ES6 classes as
well:
```js
const EventEmitter = require('events');

79
doc/api/stream.md

@ -741,8 +741,8 @@ the [`'drain'`][] event before writing more data.
To implement any sort of stream, the pattern is the same:
1. Extend the appropriate parent class in your own subclass. (The
[`util.inherits()`][] method is particularly helpful for this.)
1. Extend the appropriate parent class in your own subclass via the `extends`
keyword.
2. Call the appropriate parent class constructor in your constructor,
to be sure that the internal mechanisms are set up properly.
3. Implement one or more specific methods, as detailed below.
@ -945,10 +945,10 @@ could wrap the low-level source object by doing something like this:
// and an `ondata` member that gets called when it has data, and
// an `onend` member that gets called when the data is over.
util.inherits(SourceWrapper, Readable);
function SourceWrapper(options) {
Readable.call(this, options);
class SourceWrapper extends Readable {
constructor(options) {
super(options);
this._source = getLowlevelSourceObject();
@ -964,12 +964,12 @@ function SourceWrapper(options) {
this.push(null);
};
}
// _read will be called when the stream wants to pull more data in
// the advisory size argument is ignored in this case.
SourceWrapper.prototype._read = function(size) {
_read(size) {
this._source.readStart();
};
}
}
```
#### Example: A Counting Stream
@ -981,16 +981,15 @@ from 1 to 1,000,000 in ascending order, and then ends.
```js
const Readable = require('stream').Readable;
const util = require('util');
util.inherits(Counter, Readable);
function Counter(opt) {
Readable.call(this, opt);
class Counter extends Readable {
constructor(opt) {
super(opt);
this._max = 1000000;
this._index = 1;
}
Counter.prototype._read = function() {
_read() {
var i = this._index++;
if (i > this._max)
this.push(null);
@ -999,7 +998,8 @@ Counter.prototype._read = function() {
var buf = Buffer.from(str, 'ascii');
this.push(buf);
}
};
}
}
```
#### Example: SimpleProtocol v1 (Sub-optimal)
@ -1022,15 +1022,11 @@ However, this would be better implemented as a [Transform][] stream. See
// alternative example below under the Transform section.
const Readable = require('stream').Readable;
const util = require('util');
util.inherits(SimpleProtocol, Readable);
function SimpleProtocol(source, options) {
if (!(this instanceof SimpleProtocol))
return new SimpleProtocol(source, options);
class SimpleProtocol extends Readable {
constructor(source, options) {
super(options);
Readable.call(this, options);
this._inBody = false;
this._sawFirstCr = false;
@ -1051,7 +1047,7 @@ function SimpleProtocol(source, options) {
this.header = null;
}
SimpleProtocol.prototype._read = function(n) {
_read(n) {
if (!this._inBody) {
var chunk = this._source.read();
@ -1108,8 +1104,8 @@ SimpleProtocol.prototype._read = function(n) {
var chunk = this._source.read();
if (chunk) this.push(chunk);
}
};
}
}
// Usage:
// var parser = new SimpleProtocol(source);
// Now parser is a readable stream that will emit 'header'
@ -1242,22 +1238,19 @@ would be piped into the parser, which is a more idiomatic Node.js stream
approach.
```javascript
const util = require('util');
const Transform = require('stream').Transform;
util.inherits(SimpleProtocol, Transform);
function SimpleProtocol(options) {
if (!(this instanceof SimpleProtocol))
return new SimpleProtocol(options);
class SimpleProtocol extends Transform {
constructor(options) {
super(options);
Transform.call(this, options);
this._inBody = false;
this._sawFirstCr = false;
this._rawHeader = [];
this.header = null;
}
SimpleProtocol.prototype._transform = function(chunk, encoding, done) {
_transform(chunk, encoding, done) {
if (!this._inBody) {
// check if the chunk has a \n\n
var split = -1;
@ -1300,8 +1293,8 @@ SimpleProtocol.prototype._transform = function(chunk, encoding, done) {
this.push(chunk);
}
done();
};
}
}
// Usage:
// var parser = new SimpleProtocol();
// source.pipe(parser)
@ -1636,23 +1629,19 @@ respectively. These options can be used to implement parsers and
serializers with Transform streams.
```js
const util = require('util');
const StringDecoder = require('string_decoder').StringDecoder;
const Transform = require('stream').Transform;
util.inherits(JSONParseStream, Transform);
// Gets \n-delimited JSON string data, and emits the parsed objects
function JSONParseStream() {
if (!(this instanceof JSONParseStream))
return new JSONParseStream();
Transform.call(this, { readableObjectMode : true });
class JSONParseStream extends Transform {
constructor() {
super({ readableObjectMode : true });
this._buffer = '';
this._decoder = new StringDecoder('utf8');
}
JSONParseStream.prototype._transform = function(chunk, encoding, cb) {
_transform(chunk, encoding, cb) {
this._buffer += this._decoder.write(chunk);
// split on newlines
var lines = this._buffer.split(/\r?\n/);
@ -1670,9 +1659,9 @@ JSONParseStream.prototype._transform = function(chunk, encoding, cb) {
this.push(obj);
}
cb();
};
}
JSONParseStream.prototype._flush = function(cb) {
_flush(cb) {
// Just handle any leftover
var rem = this._buffer.trim();
if (rem) {
@ -1686,7 +1675,8 @@ JSONParseStream.prototype._flush = function(cb) {
this.push(obj);
}
cb();
};
}
}
```
### `stream.read(0)`
@ -1739,7 +1729,6 @@ horribly wrong.
[`stream.unpipe()`]: #stream_readable_unpipe_destination
[`stream.wrap()`]: #stream_readable_wrap_stream
[`tls.CryptoStream`]: tls.html#tls_class_cryptostream
[`util.inherits()`]: util.html#util_util_inherits_constructor_superconstructor
[API for Stream Consumers]: #stream_api_for_stream_consumers
[API for Stream Implementors]: #stream_api_for_stream_implementors
[child process stdin]: child_process.html#child_process_child_stdin

5
doc/api/util.md

@ -126,6 +126,10 @@ util.format(1, 2, 3); // '1 2 3'
## util.inherits(constructor, superConstructor)
_Note: usage of util.inherits() is discouraged. Please use the ES6 `class` and
`extends` keywords to get language level inheritance support. Also note that
the two styles are [semantically incompatible][]._
Inherit the prototype methods from one [constructor][] into another. The
prototype of `constructor` will be set to a new object created from
`superConstructor`.
@ -588,6 +592,7 @@ similar built-in functionality through `Object.assign`.
[`Array.isArray`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray
[constructor]: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Object/constructor
[semantically incompatible]: https://github.com/nodejs/node/issues/4179
[Customizing `util.inspect` colors]: #util_customizing_util_inspect_colors
[here]: #util_customizing_util_inspect_colors
[`Error`]: errors.html#errors_class_error

Loading…
Cancel
Save