Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "util: move util._extend to eol" #53429

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion benchmark/es/spread-assign.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
'use strict';

const common = require('../common.js');
const util = require('util');

const bench = common.createBenchmark(main, {
method: ['spread', 'assign'],
method: ['spread', 'assign', '_extend'],
count: [5, 10, 20],
n: [1e6],
});
Expand All @@ -17,6 +18,12 @@ function main({ n, context, count, rest, method }) {
let obj;

switch (method) {
case '_extend':
bench.start();
for (let i = 0; i < n; i++)
obj = util._extend({}, src);
bench.end(n);
break;
case 'assign':
bench.start();
for (let i = 0; i < n; i++)
Expand Down
30 changes: 30 additions & 0 deletions benchmark/misc/util-extend-vs-object-assign.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
'use strict';

const common = require('../common.js');
const util = require('util');

const bench = common.createBenchmark(main, {
type: ['extend', 'assign'],
n: [10e4],
});

function main({ n, type }) {
let fn;
if (type === 'extend') {
fn = util._extend;
} else if (type === 'assign') {
fn = Object.assign;
}

// Force-optimize the method to test so that the benchmark doesn't
// get disrupted by the optimizer kicking in halfway through.
for (let i = 0; i < type.length * 10; i += 1)
fn({}, process.env);

const obj = new Proxy({}, { set: function(a, b, c) { return true; } });

bench.start();
for (let j = 0; j < n; j += 1)
fn(obj, process.env);
bench.end(n);
}
8 changes: 3 additions & 5 deletions doc/api/deprecations.md
Original file line number Diff line number Diff line change
Expand Up @@ -1408,9 +1408,6 @@ requirements and complexity of your application.

<!-- YAML
changes:
- version: REPLACEME
pr-url: https://github.com/nodejs/node/pull/52744
description: End-of-Life deprecation.
- version: v22.0.0
pr-url: https://github.com/nodejs/node/pull/50488
description: Runtime deprecation.
Expand All @@ -1422,9 +1419,9 @@ changes:
description: Documentation-only deprecation.
-->

Type: End-of-Life
Type: Runtime

The `util._extend()` API has been removed because it's an unmaintained
The [`util._extend()`][] API is deprecated because it's an unmaintained
legacy API that was exposed to user land by accident.
Please use `target = Object.assign(target, source)` instead.

Expand Down Expand Up @@ -3836,6 +3833,7 @@ and [`crypto.setEngine()`][] all depend on this functionality from OpenSSL.
[`url.format()`]: url.md#urlformaturlobject
[`url.parse()`]: url.md#urlparseurlstring-parsequerystring-slashesdenotehost
[`url.resolve()`]: url.md#urlresolvefrom-to
[`util._extend()`]: util.md#util_extendtarget-source
[`util.getSystemErrorName()`]: util.md#utilgetsystemerrornameerr
[`util.inspect()`]: util.md#utilinspectobject-options
[`util.inspect.custom`]: util.md#utilinspectcustom
Expand Down
19 changes: 19 additions & 0 deletions doc/api/util.md
Original file line number Diff line number Diff line change
Expand Up @@ -2923,6 +2923,24 @@ util.types.isWeakSet(new WeakSet()); // Returns true
The following APIs are deprecated and should no longer be used. Existing
applications and modules should be updated to find alternative approaches.

### `util._extend(target, source)`

<!-- YAML
added: v0.7.5
deprecated: v6.0.0
-->

> Stability: 0 - Deprecated: Use [`Object.assign()`][] instead.

* `target` {Object}
* `source` {Object}

The `util._extend()` method was never intended to be used outside of internal
Node.js modules. The community found and used it anyway.

It is deprecated and should not be used in new code. JavaScript comes with very
similar built-in functionality through [`Object.assign()`][].

### `util.isArray(object)`

<!-- YAML
Expand Down Expand Up @@ -2972,6 +2990,7 @@ util.isArray({});
[`JSON.stringify()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
[`MIMEparams`]: #class-utilmimeparams
[`Map`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map
[`Object.assign()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
[`Object.freeze()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
[`Promise`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
[`Proxy`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy
Expand Down
23 changes: 23 additions & 0 deletions lib/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,26 @@ function inherits(ctor, superCtor) {
ObjectSetPrototypeOf(ctor.prototype, superCtor.prototype);
}

/**
* @deprecated since v6.0.0
* @template T
* @template S
* @param {T} target
* @param {S} source
* @returns {S extends null ? T : (T & S)}
*/
function _extend(target, source) {
// Don't do anything if source isn't an object
if (source === null || typeof source !== 'object') return target;

const keys = ObjectKeys(source);
let i = keys.length;
while (i--) {
target[keys[i]] = source[keys[i]];
}
return target;
}

const callbackifyOnRejected = (reason, cb) => {
// `!reason` guard inspired by bluebird (Ref: https://goo.gl/t5IS6M).
// Because `null` is a special error value in callbacks which means "no error
Expand Down Expand Up @@ -259,6 +279,9 @@ function parseEnv(content) {
module.exports = {
_errnoException,
_exceptionWithHostPort,
_extend: deprecate(_extend,
'The `util._extend` API is deprecated. Please use Object.assign() instead.',
'DEP0060'),
callbackify,
debug: debuglog,
debuglog,
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/tls-connect.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ exports.connect = function connect(options, callback) {
}).listen(0, function() {
server.server = this;

const optClient = Object.assign({
const optClient = util._extend({
port: this.address().port,
}, options.client);

Expand Down
9 changes: 9 additions & 0 deletions test/parallel/test-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,15 @@ assert.strictEqual(util.isArray(/regexp/), false);
assert.strictEqual(util.isArray(new Error()), false);
assert.strictEqual(util.isArray({ __proto__: Array.prototype }), false);

// _extend
assert.deepStrictEqual(util._extend({ a: 1 }), { a: 1 });
assert.deepStrictEqual(util._extend({ a: 1 }, []), { a: 1 });
assert.deepStrictEqual(util._extend({ a: 1 }, null), { a: 1 });
assert.deepStrictEqual(util._extend({ a: 1 }, true), { a: 1 });
assert.deepStrictEqual(util._extend({ a: 1 }, false), { a: 1 });
assert.deepStrictEqual(util._extend({ a: 1 }, { b: 2 }), { a: 1, b: 2 });
assert.deepStrictEqual(util._extend({ a: 1, b: 2 }, { b: 3 }), { a: 1, b: 3 });

assert.strictEqual(util.toUSVString('string\ud801'), 'string\ufffd');

{
Expand Down
Loading