diff --git a/lib/internal/per_context/primordials.js b/lib/internal/per_context/primordials.js index c30451b05bdac2..358a3ffb1909ea 100644 --- a/lib/internal/per_context/primordials.js +++ b/lib/internal/per_context/primordials.js @@ -81,6 +81,9 @@ function copyPropsRenamed(src, dest, prefix) { ReflectDefineProperty(dest, name, desc); if (varargsMethods.includes(name)) { ReflectDefineProperty(dest, `${name}Apply`, { + // `src` is bound as the `this` so that the static `this` points + // to the object it was defined on, + // e.g.: `ArrayOfApply` gets a `this` of `Array`: value: applyBind(desc.value, src), }); } diff --git a/lib/readline.js b/lib/readline.js index a284cc8afcf0d0..bad4774a6a4162 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -43,6 +43,7 @@ const { MathCeil, MathFloor, MathMax, + MathMaxApply, NumberIsFinite, NumberIsNaN, ObjectDefineProperty, @@ -634,7 +635,7 @@ Interface.prototype._tabComplete = function(lastKeypressWasTab) { // Apply/show completions. const completionsWidth = ArrayPrototypeMap(completions, (e) => getStringWidth(e)); - const width = MathMax(...completionsWidth) + 2; // 2 space padding + const width = MathMaxApply(completionsWidth) + 2; // 2 space padding let maxColumns = MathFloor(this.columns / width) || 1; if (maxColumns === Infinity) { maxColumns = 1; diff --git a/lib/zlib.js b/lib/zlib.js index 7812f5169545d1..5fcd736f6652a1 100644 --- a/lib/zlib.js +++ b/lib/zlib.js @@ -28,7 +28,7 @@ const { ArrayPrototypePush, Error, FunctionPrototypeBind, - MathMax, + MathMaxApply, NumberIsFinite, NumberIsNaN, ObjectDefineProperties, @@ -788,7 +788,7 @@ function createConvenienceMethod(ctor, sync) { }; } -const kMaxBrotliParam = MathMax(...ArrayPrototypeMap( +const kMaxBrotliParam = MathMaxApply(ArrayPrototypeMap( ObjectKeys(constants), (key) => (StringPrototypeStartsWith(key, 'BROTLI_PARAM_') ? constants[key] : diff --git a/test/parallel/test-primordials-apply.js b/test/parallel/test-primordials-apply.js new file mode 100644 index 00000000000000..0901a87ba18777 --- /dev/null +++ b/test/parallel/test-primordials-apply.js @@ -0,0 +1,74 @@ +// Flags: --expose-internals +'use strict'; + +require('../common'); + +const assert = require('assert'); +const { + ArrayOfApply, + ArrayPrototypePushApply, + ArrayPrototypeUnshiftApply, + MathMaxApply, + MathMinApply, + StringPrototypeConcatApply, + TypedArrayOfApply, +} = require('internal/test/binding').primordials; + +{ + const arr1 = [1, 2, 3]; + const arr2 = ArrayOfApply(arr1); + + assert.deepStrictEqual(arr2, arr1); + assert.notStrictEqual(arr2, arr1); +} + +{ + const array = [1, 2, 3]; + const i32Array = TypedArrayOfApply(Int32Array, array); + + assert(i32Array instanceof Int32Array); + assert.strictEqual(i32Array.length, array.length); + for (let i = 0, { length } = array; i < length; i++) { + assert.strictEqual(i32Array[i], array[i], `i32Array[${i}] === array[${i}]`); + } +} + +{ + const arr1 = [1, 2, 3]; + const arr2 = [4, 5, 6]; + + const expected = [...arr1, ...arr2]; + + assert.strictEqual(ArrayPrototypePushApply(arr1, arr2), expected.length); + assert.deepStrictEqual(arr1, expected); +} + +{ + const arr1 = [1, 2, 3]; + const arr2 = [4, 5, 6]; + + const expected = [...arr2, ...arr1]; + + assert.strictEqual(ArrayPrototypeUnshiftApply(arr1, arr2), expected.length); + assert.deepStrictEqual(arr1, expected); +} + +{ + const array = [1, 2, 3]; + assert.strictEqual(MathMaxApply(array), 3); + assert.strictEqual(MathMinApply(array), 1); +} + +{ + let hint; + const obj = { [Symbol.toPrimitive](h) { + hint = h; + return '[object Object]'; + } }; + + const args = ['foo ', obj, ' bar']; + const result = StringPrototypeConcatApply('', args); + + assert.strictEqual(hint, 'string'); + assert.strictEqual(result, 'foo [object Object] bar'); +}