@@ -269,6 +269,61 @@ ReflectApply(func, null, array);
269269
270270<details >
271271
272+ <summary ><code >%Array.prototype.concat%</code > looks up
273+ <code>@@isConcatSpreadable</code> property of the passed
274+ arguments and the <code>this</code> value.</summary>
275+
276+ ``` js
277+ {
278+ // Unsafe code example:
279+ // 1. Lookup @@isConcatSpreadable property on `array` (user-mutable if
280+ // user-provided).
281+ // 2. Lookup @@isConcatSpreadable property on `%Array.prototype%
282+ // (user-mutable).
283+ // 2. Lookup @@isConcatSpreadable property on `%Object.prototype%
284+ // (user-mutable).
285+ const array = [];
286+ ArrayPrototypeConcat (array);
287+ }
288+ ```
289+
290+ ``` js
291+ // User-land
292+ Object .defineProperty (Object .prototype , Symbol .isConcatSpreadable , {
293+ get () {
294+ this .push (5 );
295+ return true ;
296+ },
297+ });
298+
299+ // Core
300+ {
301+ // Using ArrayPrototypeConcat does not produce the expected result:
302+ const a = [1 , 2 ];
303+ const b = [3 , 4 ];
304+ console .log (ArrayPrototypeConcat (a, b)); // [1, 2, 5, 3, 4, 5]
305+ }
306+ {
307+ // Concatenating two arrays can be achieved safely, e.g.:
308+ const a = [1 , 2 ];
309+ const b = [3 , 4 ];
310+ // Using %Array.prototype.push% and `SafeArrayIterator` to get the expected
311+ // outcome:
312+ const concatArray = [];
313+ ArrayPrototypePush (concatArray, ... new SafeArrayIterator (a),
314+ ... new SafeArrayIterator (b));
315+ console .log (concatArray); // [1, 2, 3, 4]
316+
317+ // Or using `ArrayPrototypePushApply` if it's OK to mutate the first array:
318+ ArrayPrototypePushApply (a, b);
319+ console .log (a); // [1, 2, 3, 4]
320+ }
321+ ```
322+
323+ </details >
324+
325+ <details >
326+
272327<summary ><code >%Object.fromEntries%</code > iterate over an array</summary >
273328
274329``` js
0 commit comments