Briefly
The concat
method combines the original array with one or more specified arrays or other values and returns a new array. The method does not change the arrays involved in the merging.
Example
Let's combine two arrays into a new array. Note that the original array remains unchanged:
const months = ['March', 'April', 'May']const summer = ['June', 'July', 'August']const favoriteMonths = months.concat(summer)console.log(favoriteMonths)// ['March', 'April', 'May', 'June', 'July', 'August']console.log(months)// ['March', 'April', 'May']
const months = ['March', 'April', 'May'] const summer = ['June', 'July', 'August'] const favoriteMonths = months.concat(summer) console.log(favoriteMonths) // ['March', 'April', 'May', 'June', 'July', 'August'] console.log(months) // ['March', 'April', 'May']
Let's combine three arrays into a new array, using an empty array as the original:
const numbers = [2, 12, 85]const strings = ['06', 'this', 'is', 'your', 'number']const result = [].concat(numbers, strings)console.log(result)// [2, 12, 85, '06', 'this', 'is', 'your', 'number']
const numbers = [2, 12, 85] const strings = ['06', 'this', 'is', 'your', 'number'] const result = [].concat(numbers, strings) console.log(result) // [2, 12, 85, '06', 'this', 'is', 'your', 'number']
How it works
concat
accepts as arguments the elements that are merged into a new array.
concat
returns a new array obtained by merging.
If the method is called without arguments for an array, a shallow copy of the original array is returned:
const numbers = [1, 2, 3, 4]const copyNumbers = numbers.concat()console.log(copyNumbers)// [1, 2, 3, 4]console.log(numbers)// [1, 2, 3, 4]
const numbers = [1, 2, 3, 4] const copyNumbers = numbers.concat() console.log(copyNumbers) // [1, 2, 3, 4] console.log(numbers) // [1, 2, 3, 4]
Arguments can include not only arrays but also values of other types:
const numbers = [1, 2, 3]const result = numbers.concat( 4, 'five', null, {name: 'six'}, [[7]])console.log(result)// [1, 2, 3, 4, 'five', null, {name: 'six'}, [7]]
const numbers = [1, 2, 3] const result = numbers.concat( 4, 'five', null, {name: 'six'}, [[7]] ) console.log(result) // [1, 2, 3, 4, 'five', null, {name: 'six'}, [7]]
The concat
method can also be called for values of other types (e.g., string, number, object). If this
is a primitive type value (string, number, true
, or false
), it is converted into an object.
More about conversion to object
For primitive values, a corresponding wrapper object will be created, for example: true
— Boolean
, 'string'
— String
, 48
— Number
.
For undefined
and null
, conversion to an object cannot be performed, as these values do not have wrapper objects.
Examples of using the concat
method when the original value is not an array:
const concatFn = Array.prototype.concatconst str = 'I am a string'console.log(concatFn.call(str))// [ [String: 'I am a string'] ]const number = 42console.log(concatFn.call(number, 21))// [ [Number: 42], 21 ]
const concatFn = Array.prototype.concat const str = 'I am a string' console.log(concatFn.call(str)) // [ [String: 'I am a string'] ] const number = 42 console.log(concatFn.call(number, 21)) // [ [Number: 42], 21 ]
In case of trying to use undefined
or null
as the original value of the Array
method, a Type
will be thrown.
try { console.log(concatFn.call(null))} catch(err) { console.error('Caught an error! Here it is:', err.message)}// Caught an error! Here it is:// Array.prototype.concat called on null or undefined
try { console.log(concatFn.call(null)) } catch(err) { console.error('Caught an error! Here it is:', err.message) } // Caught an error! Here it is: // Array.prototype.concat called on null or undefined
Understanding
concat
is typically used when it is necessary to obtain a new array by merging several arrays. Unlike the splice
method, which can be used to add elements to the original array, the concat
method creates a new array and does not modify the original.
If the argument includes a non-one-dimensional array, that array will be added as a single element:
const numbers = [1, 2, 3]console.log(numbers.concat([4, [5, 6]]))// [1, 2, 3, 4, [5, 6]]
const numbers = [1, 2, 3] console.log(numbers.concat([4, [5, 6]])) // [1, 2, 3, 4, [5, 6]]
The standard behavior of the method can be modified using Symbol
.
More about using `Symbol.isConcatSpreadable`
According to the ECMAScript specification, a special property Symbol
can be used to change the behavior of the method.
If the value of this property for the array is false
, it will be added as a single element:
const numbers = [1, 2, 3]const otherNumbers = [4, 5, 6]otherNumbers[Symbol.isConcatSpreadable] = falseconsole.log(numbers.concat(otherNumbers))// [1, 2, 3, [4, 5, 6, [Symbol(Symbol.isConcatSpreadable)]: false ]]// ------------------------------------------------------
const numbers = [1, 2, 3] const otherNumbers = [4, 5, 6] otherNumbers[Symbol.isConcatSpreadable] = false console.log(numbers.concat(otherNumbers)) // [1, 2, 3, [4, 5, 6, [Symbol(Symbol.isConcatSpreadable)]: false ]] // ------------------------------------------------------
If the value of this property for an array-like object is true
, its property elements will be added separately:
const numbers = [1, 2, 3]const arrayLike = { [Symbol.isConcatSpreadable]: true, '0': 4, '1': 5, '2': 6, length: 3}console.log(numbers.concat(arrayLike))// [1, 2, 3, 4, 5, 6]console.log(numbers.concat({''}))
const numbers = [1, 2, 3] const arrayLike = { [Symbol.isConcatSpreadable]: true, '0': 4, '1': 5, '2': 6, length: 3 } console.log(numbers.concat(arrayLike)) // [1, 2, 3, 4, 5, 6] console.log(numbers.concat({''}))
Tips
💡 If one of the arrays has unfilled elements, then when executing concat
, the returned array will also contain unfilled elements:
const colors = ['crimson', , 'purple']console.log(colors.concat(['magenta']))// ['crimson', <1 empty item>, 'purple', 'magenta']
const colors = ['crimson', , 'purple'] console.log(colors.concat(['magenta'])) // ['crimson', <1 empty item>, 'purple', 'magenta']
💡 If the original array or one of the arguments contains objects, then the resulting array from concat
will contain references to those objects, not new ones. Thus, subsequent changes to the object will be visible in the created array and vice versa:
const skills = [{name: 'HTML'}, {name: 'CSS'}, {name: 'JS'}]// Add a new elementconst result = skills.concat([{name: 'Python'}]);console.log(result)// [{name: 'HTML'}, {name: 'CSS'}, {name: 'JS'}, {name: 'Python'}]// Change an element of the original arrayskills[1].level = 'C'console.log(skills)// [{name: 'HTML'}, {name: 'CSS', level: 'C'}, {name: 'JS'}]// See the changes in the created arrayconsole.log(result)// [// { name: 'HTML'},// { name: 'CSS', level: 'C'},// { name: 'JS' },// { name: 'Python' }// ]
const skills = [{name: 'HTML'}, {name: 'CSS'}, {name: 'JS'}] // Add a new element const result = skills.concat([{name: 'Python'}]); console.log(result) // [{name: 'HTML'}, {name: 'CSS'}, {name: 'JS'}, {name: 'Python'}] // Change an element of the original array skills[1].level = 'C' console.log(skills) // [{name: 'HTML'}, {name: 'CSS', level: 'C'}, {name: 'JS'}] // See the changes in the created array console.log(result) // [ // { name: 'HTML'}, // { name: 'CSS', level: 'C'}, // { name: 'JS' }, // { name: 'Python' } // ]