Skip to content

Commit 3ff956a

Browse files
javachemeta-codesync[bot]
authored andcommitted
Polyfill Array copying methods (#59091)
Summary: Pull Request resolved: #59091 Install guarded `Array.prototype.toSorted` and `Array.prototype.toReversed` polyfills during React Native environment setup. Both methods return shallow copies and preserve native implementations when the runtime already provides them. Register the language polyfills from the default environment setup rather than coupling them to generic global-variable setup. Changelog: [General][Added] - Polyfill `Array.prototype.toSorted` and `Array.prototype.toReversed` when the JavaScript runtime does not provide them Reviewed By: mweststrate Differential Revision: D125283374 fbshipit-source-id: 7b195319f6ba316fc73ede4d81c6431cb46ccb23
1 parent 210b1fb commit 3ff956a

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)