@@ -269,6 +269,61 @@ ReflectApply(func, null, array);
269
269
270
270
<details >
271
271
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
+
272
327
<summary ><code >%Object.fromEntries%</code > iterate over an array</summary >
273
328
274
329
``` js
0 commit comments