Skip to content

Commit 9df4f1d

Browse files
aelafifimgol
authored andcommitted
Core: Use Array.prototype.flat where supported
Calling `Array.prototype.concat.apply( [], inputArray )` to flatten `inputArray` crashes for large arrays; using `Array.prototype.flat` avoids these issues in browsers that support it. In case it's necessary to support these large arrays even in older browsers, a polyfill for `Array.prototype.flat` can be loaded. This is already being done by many applications. Fixes gh-4320 Closes gh-4459
1 parent aa6344b commit 9df4f1d

File tree

5 files changed

+39
-14
lines changed

5 files changed

+39
-14
lines changed

src/core.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ define( [
66
"./var/arr",
77
"./var/getProto",
88
"./var/slice",
9-
"./var/concat",
9+
"./var/flat",
1010
"./var/push",
1111
"./var/indexOf",
1212
"./var/class2type",
@@ -18,7 +18,7 @@ define( [
1818
"./var/isWindow",
1919
"./core/DOMEval",
2020
"./core/toType"
21-
], function( arr, getProto, slice, concat, push, indexOf,
21+
], function( arr, getProto, slice, flat, push, indexOf,
2222
class2type, toString, hasOwn, fnToString, ObjectFunctionString,
2323
support, isWindow, DOMEval, toType ) {
2424

@@ -397,7 +397,7 @@ jQuery.extend( {
397397
}
398398

399399
// Flatten any nested arrays
400-
return concat.apply( [], ret );
400+
return flat( ret );
401401
},
402402

403403
// A global GUID counter for objects

src/manipulation.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
define( [
22
"./core",
33
"./core/isAttached",
4-
"./var/concat",
4+
"./var/flat",
55
"./var/isIE",
66
"./var/push",
77
"./core/access",
@@ -22,7 +22,7 @@ define( [
2222
"./traversing",
2323
"./selector",
2424
"./event"
25-
], function( jQuery, isAttached, concat, isIE, push, access, rtagName,
25+
], function( jQuery, isAttached, flat, isIE, push, access, rtagName,
2626
rscriptType, wrapMap, getAll, setGlobalEval, buildFragment,
2727
dataPriv, dataUser, acceptData, DOMEval, nodeName ) {
2828

@@ -103,7 +103,7 @@ function cloneCopyEvent( src, dest ) {
103103
function domManip( collection, args, callback, ignored ) {
104104

105105
// Flatten any nested arrays
106-
args = concat.apply( [], args );
106+
args = flat( args );
107107

108108
var fragment, first, scripts, hasScripts, node, doc,
109109
i = 0,

src/var/concat.js

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/var/flat.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
define( [
2+
"./arr"
3+
], function( arr ) {
4+
5+
"use strict";
6+
7+
// Support: IE 11+, Edge 18+
8+
// Provide fallback for browsers without Array#flat.
9+
return arr.flat ? function( array ) {
10+
return arr.flat.call( array );
11+
} : function( array ) {
12+
return arr.concat.apply( [], array );
13+
};
14+
15+
} );

test/unit/core.js

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ QUnit.test( "map()", function( assert ) {
681681
} );
682682

683683
QUnit.test( "jQuery.map", function( assert ) {
684-
assert.expect( 25 );
684+
assert.expect( 28 );
685685

686686
var i, label, result, callback;
687687

@@ -781,6 +781,23 @@ QUnit.test( "jQuery.map", function( assert ) {
781781
return k % 2 ? k : [ k, k, k ];
782782
} );
783783
assert.equal( result.join( "" ), "00012223", "Array results flattened (#2616)" );
784+
785+
result = jQuery.map( [ [ [ 1, 2 ], 3 ], 4 ], function( v, k ) {
786+
return v;
787+
} );
788+
assert.equal( result.length, 3, "Array flatten only one level down" );
789+
assert.ok( Array.isArray( result[ 0 ] ), "Array flatten only one level down" );
790+
791+
// Support: IE 11+, Edge 18+
792+
// Skip the test in browsers without Array#flat.
793+
if ( Array.prototype.flat ) {
794+
result = jQuery.map( Array( 300000 ), function( v, k ) {
795+
return k;
796+
} );
797+
assert.equal( result.length, 300000, "Able to map 300000 records without any problems (#4320)" );
798+
} else {
799+
assert.ok( "skip", "Array#flat doesn't supported on all browsers" );
800+
}
784801
} );
785802

786803
QUnit.test( "jQuery.merge()", function( assert ) {

0 commit comments

Comments
 (0)