diff --git a/CHANGELOG.md b/CHANGELOG.md index 680922a78fbb..2f28e8917420 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## Changelog ##### Unreleased +- Changed the order of operations in `%TypedArray%.prototype.with` following [proposal-change-array-by-copy/86](https://github.com/tc39/proposal-change-array-by-copy/issues/86) - Fixed a bug in the order of getting flags in `RegExp.prototype.flags` in the actual version of V8 - Fixed property descriptors of some `Math` and `Number` constants - Added detection of NodeJS [bug](https://github.com/nodejs/node/issues/41038) in `structuredClone` that can not clone `DOMException` (just in case for future versions that will fix other issues) diff --git a/packages/core-js/modules/esnext.typed-array.with.js b/packages/core-js/modules/esnext.typed-array.with.js index 9936f839c90d..95344096ddb5 100644 --- a/packages/core-js/modules/esnext.typed-array.with.js +++ b/packages/core-js/modules/esnext.typed-array.with.js @@ -1,22 +1,32 @@ 'use strict'; var arrayWith = require('../internals/array-with'); var ArrayBufferViewCore = require('../internals/array-buffer-view-core'); -// var toIntegerOrInfinity = require('../internals/to-integer-or-infinity'); -// var toBigInt = require('../internals/to-big-int'); -// var classof = require('../internals/classof'); -// var uncurryThis = require('../internals/function-uncurry-this'); +var toIntegerOrInfinity = require('../internals/to-integer-or-infinity'); +var toBigInt = require('../internals/to-big-int'); +var classof = require('../internals/classof'); +var uncurryThis = require('../internals/function-uncurry-this'); var aTypedArray = ArrayBufferViewCore.aTypedArray; var exportTypedArrayMethod = ArrayBufferViewCore.exportTypedArrayMethod; var TYPED_ARRAY_CONSTRUCTOR = ArrayBufferViewCore.TYPED_ARRAY_CONSTRUCTOR; -// var slice = uncurryThis(''.slice); +var slice = uncurryThis(''.slice); + +var PROPER_ORDER = !!function () { + try { + // eslint-disable-next-line no-throw-literal, es-x/no-typed-arrays -- required for testing + new Int8Array(1)['with'](2, { valueOf: function () { throw 8; } }); + } catch (error) { + // some early implementations, like WebKit, does not follow the final semantic + // https://github.com/tc39/proposal-change-array-by-copy/pull/86 + return error === 8; + } +}(); // `%TypedArray%.prototype.with` method // https://tc39.es/proposal-change-array-by-copy/#sec-%typedarray%.prototype.with exportTypedArrayMethod('with', { 'with': function (index, value) { - // aTypedArray(this); - // var relativeIndex = toIntegerOrInfinity(index); - // var actualValue = slice(classof(this), 0, 3) === 'Big' ? toBigInt(value) : +value; - // return arrayWith(this, this[TYPED_ARRAY_CONSTRUCTOR], relativeIndex, actualValue); - return arrayWith(aTypedArray(this), this[TYPED_ARRAY_CONSTRUCTOR], index, value); -} }['with']); + aTypedArray(this); + var relativeIndex = toIntegerOrInfinity(index); + var actualValue = slice(classof(this), 0, 3) === 'Big' ? toBigInt(value) : +value; + return arrayWith(this, this[TYPED_ARRAY_CONSTRUCTOR], relativeIndex, actualValue); +} }['with'], !PROPER_ORDER); diff --git a/tests/compat/tests.js b/tests/compat/tests.js index e839ea1ea1eb..4fd55421c0e1 100644 --- a/tests/compat/tests.js +++ b/tests/compat/tests.js @@ -1704,7 +1704,11 @@ GLOBAL.tests = { return Int8Array.prototype.uniqueBy; }, 'esnext.typed-array.with': function () { - return Int8Array.prototype['with']; + try { + new Int8Array(1)['with'](2, { valueOf: function () { throw 8; } }); + } catch (error) { + return error === 8; + } }, 'esnext.weak-map.delete-all': function () { return WeakMap.prototype.deleteAll; diff --git a/tests/tests/esnext.typed-array.with.js b/tests/tests/esnext.typed-array.with.js index 5dff50fda46c..fb3a087c2de6 100644 --- a/tests/tests/esnext.typed-array.with.js +++ b/tests/tests/esnext.typed-array.with.js @@ -30,5 +30,15 @@ if (DESCRIPTORS) QUnit.test('%TypedArrayPrototype%.with', assert => { assert.same(new TypedArray(5).with(2, checker)[2], 10); assert.same(checker.$valueOf, 1, 'valueOf calls'); assert.same(checker.$toString, 0, 'toString calls'); + + assert.true(!!function () { + try { + new Int8Array(1).with(2, { valueOf() { throw 8; } }); + } catch (error) { + // some early implementations, like WebKit, does not follow the final semantic + // https://github.com/tc39/proposal-change-array-by-copy/pull/86 + return error === 8; + } + }(), 'proper order of operations'); } });