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

Loading…
Cancel
Save