Skip to content

Commit 3012f94

Browse files
javachefacebook-github-bot
authored andcommitted
Polyfill Array copying methods (#59091)
Summary: Install guarded `Array.prototype.toSorted` and `Array.prototype.toReversed` polyfills during default React Native environment setup. Both methods return shallow copies and preserve native implementations when the runtime already provides them. Register the language polyfills alongside the existing Promise setup rather than coupling them to the generic global-variable setup. Changelog: [General][Added] - Polyfill `Array.prototype.toSorted` and `Array.prototype.toReversed` when the JavaScript runtime does not provide them Differential Revision: D125283374
1 parent a7a6b39 commit 3012f94

3 files changed

Lines changed: 89 additions & 0 deletions

File tree

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict-local
8+
* @format
9+
* @fantom_hermes_variant *
10+
*/
11+
12+
'use strict';
13+
14+
const originalToSorted = Array.prototype.toSorted;
15+
const originalToReversed = Array.prototype.toReversed;
16+
17+
require('@react-native/fantom/src/setUpDefaultReactNativeEnvironment');
18+
19+
describe('Array ES2023 method polyfills', () => {
20+
it('preserves native methods and fills missing methods', () => {
21+
if (originalToSorted == null) {
22+
expect(Array.prototype.toSorted).toBeDefined();
23+
} else {
24+
expect(Array.prototype.toSorted).toBe(originalToSorted);
25+
}
26+
27+
if (originalToReversed == null) {
28+
expect(Array.prototype.toReversed).toBeDefined();
29+
} else {
30+
expect(Array.prototype.toReversed).toBe(originalToReversed);
31+
}
32+
});
33+
34+
it('provides non-mutating copying behavior', () => {
35+
const input = [3, 1, 2];
36+
37+
expect(input.toSorted((a, b) => a - b)).toEqual([1, 2, 3]);
38+
expect(input.toReversed()).toEqual([2, 1, 3]);
39+
expect(input).toEqual([3, 1, 2]);
40+
expect(
41+
Object.getOwnPropertyDescriptor(Array.prototype, 'toSorted')?.enumerable,
42+
).toBe(false);
43+
expect(
44+
Object.getOwnPropertyDescriptor(Array.prototype, 'toReversed')
45+
?.enumerable,
46+
).toBe(false);
47+
});
48+
});
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/**
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*
7+
* @flow strict
8+
* @format
9+
*/
10+
11+
'use strict';
12+
13+
const arrayPrototype = Array.prototype;
14+
15+
if (arrayPrototype.toSorted == null) {
16+
Object.defineProperty(arrayPrototype, 'toSorted' as string, {
17+
configurable: true,
18+
value: function <T>(
19+
this: Array<T>,
20+
compareFn?: (a: T, b: T) => number,
21+
): Array<T> {
22+
const copy = Array.from(this);
23+
copy.sort(compareFn);
24+
return copy;
25+
},
26+
writable: true,
27+
});
28+
}
29+
30+
if (arrayPrototype.toReversed == null) {
31+
Object.defineProperty(arrayPrototype, 'toReversed' as string, {
32+
configurable: true,
33+
value: function <T>(this: Array<T>): Array<T> {
34+
const copy = Array.from(this);
35+
copy.reverse();
36+
return copy;
37+
},
38+
writable: true,
39+
});
40+
}

‎packages/react-native/src/private/setup/setUpDefaultReactNativeEnvironment.js‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ export default function setUpDefaultReactNativeEnvironment(
2323
require('./setUpDOM').default();
2424
require('./setUpPerformance').default();
2525
require('../../../Libraries/Core/polyfillPromise');
26+
require('../../../Libraries/Core/polyfillArrayES2023Methods');
2627
require('../../../Libraries/Core/setUpTimers');
2728
if (__DEV__ && enableDeveloperTools) {
2829
require('../../../Libraries/Core/setUpReactDevTools');

0 commit comments

Comments
 (0)