Logo

자바스크립트 배열에 원소 추가하기: push()와 unshift() 메서드

배열에 원소를 추가하는 것은 자바스크립트 코딩할 때 매우 빈번하게 필요한 작업이죠?

이번 포스팅에서는 자바스크립트 배열에 원소를 추가하는 다양한 방법에 대해서 간단히 정리해보겠습니다.

push() 메서드

자바스크립트 배열에 원소를 추가하는 방법 중에서 가장 널리 알려진 방법은 뭐니뭐니 해도 배열의 push() 메서드일 것 같은데요.

예를 들어, push() 메서드로 과일 이름을 담은 배열에 원소를 추가해보겠습니다.

const fruits = ["Apple", "Banana", "Coconut"];
fruits.push("Orange"); // 4
console.log(fruits); // ['Apple', 'Banana', 'Coconut', 'Orange']

push() 메서드에 넘어온 인수는 배열의 끝, 즉 기존에 마지막 원소 바로 뒤에 추가됩니다. 그리고 결과로 원소를 추가한 후의 배열에 들어있는 원소의 수, 즉 배열의 길이를 반환합니다.

push() 메서드가 아무 것도 반환하지 않는다고 알고 계신 분들도 있을텐데요. 아무래도 배열에 원소를 추가한 후에 바로 배열의 길이가 필요한 경우가 많지 않다보니, 실용성이 많이 떨어지는 부분인 것 같습니다.

push() 메서드는 추가할 값을 가변 인자로 받기 때문에, 두 개 이상의 원소를 한 번에 추가할 수도 있습니다.

const fruits = ["Apple", "Banana", "Coconut"];
fruits.push("Orange", "Lemon"); // 5
console.log(fruits); // ['Apple', 'Banana', 'Coconut', 'Orange', 'Lemon']

unshift() 메서드

반대로 배열의 시작에 원소를 추가하고 싶을 때는 unshift() 메서드를 사용합니다.

const fruits = ["Apple", "Banana", "Coconut"];
fruits.unshift("Orange"); // 4
console.log(fruits); // ['Orange', 'Apple', 'Banana', 'Coconut']

push() 메서드와 동일하게 unshift() 메서드도 원본 배열에 원소를 추가한 후, 배열 내의 원소의 개수를 반환합니다. 뿐만 아니라, 가변 인자를 받는 부분도 동일하기 때문에 여러 개의 원소를 한 번에 추가할 수 있습니다.

여기에 추가로 꼭 기억해두셔야 할 push()unshift() 메서드의 가장 중요한 공통점이 있는데요. 바로 별도로 사본 배열 생성하여 원소를 추가하는 것이 아니라, 원본 배열에 바로 원소를 추가한다는 것입니다. 그러므로 원본 배열에 변경을 가해서는 안 되는 경우에는, 메서드를 호출하기 전에 반드시 배열을 복제해놔야 겠습니다.

const fruits = ["Apple", "Banana", "Coconut"];
const clonedFruits = [].concat(fruits); // ['Apple', 'Banana', 'Coconut']
clonedFruits.push("Orange"); // 4
clonedFruits.unshift("Lemon"); // 5
console.log(fruits); // ['Apple', 'Banana', 'Coconut']
console.log(clonedFruits); // ['Lemon', 'Apple', 'Banana', 'Coconut', 'Orange']

push() 메서드와 unshift() 메서드는 성능 측면에서 중요한 차이점이 있는데요. push() 메서드는 시간 복잡도는 O(1)이기 때문에 배열의 크기에 관계없이 상수 시간이 소모가 됩니다. 반면에 unshift() 메서드는 새로운 요소를 위해 기존에 배열에 있던 모든 요소를 한 자리씩 오른쪽으로 이동시켜야 하기 때문에 시간 복잡도가 O(n)입니다. 따라서 배열에 저장되어 있는 값의 개수가 많을수록, 그에 비례하여 시간이 오래 걸리게 됩니다.

성능에 민감한 프로그램을 작성하시거나 크기가 아주 큰 배열을 다루는 상황에서는 이러한 성능 차이를 반드시 고려되야겠습니다.

splice() 메서드

그럼, 배열의 중간에 원소를 추가하고 싶을 때는 어떻게 해야할까요? 이 때는 바로 splice()라는 배열의 다목적 메서드를 활용할 수 있습니다. (slice()가 아니고 splice()이오니 주의 바랍니다.)

splice() 메서드는 첫 번째 인자로 시작 인덱스(index), 두 번째 인자로 몇개의 값을 삭제할지, 그리고 세 번째 인자부터는 추가할 값을 가변 인자로 넘길 수 있으며, 삭제된 값을 담고 있는 배열을 반환하는데요. 단순히 배열에 원소를 추가할 때는 추가할 위치를 첫 번째 인자로 넘기고, 두 번째 인자로는 0을 넘겨서 아무 것도 삭제하지 않으면 됩니다.

그럼 배열의 인덱스 1, 즉 두 번째 위치에 원소를 추가해보겠습니다.

const fruits = ["Apple", "Banana", "Coconut"];
fruits.splice(1, 0, "Orange"); // []
console.log(fruits); // ['Apple', 'Orange', 'Banana', 'Coconut']

아무 원소도 삭제되지 않았으므로, 빈 배열이 반환되는 것을 볼 수 있습니다.

자바스크립트 배열의 slice()와 splice() 메서드에 대한 좀 더 자세한 설명은 관련 포스팅를 참고바랍니다.

spread 연산자

ES6부터는 배열을 다룰 때, spread 또는 전개 연산자로고 불리는 ... 기호가 많이 사용되는데요. 배열을 나타내는 [] 기호 안에서 배열 앞에 ... 기호를 붙이면 그 배열 내의 원소가 마치 펼쳐진 것처럼 해당 배열에 추가되기 때문에, 그 배열의 시작이든 끝이든 유연하게 원하는 개수의 원소를 추가할 수 있습니다.

const fruits = ["Apple", "Banana", "Coconut"];
const moreFruits = ["Melon", ...fruits, "Strawberry", "Orange"];
console.log(moreFruits); // ['Melon', 'Apple', 'Banana', 'Coconut', 'Strawberry', 'Orange']

특히, 전개 연산자는 메서드 체이닝(chaining), 같은 배열을 상대로 여러 메서드를 연쇄 호출할 때도 사용하기 적합합니다.

const fruits = ["Apple", "Banana", "Coconut"];
const filteredSortedMoreFruits = ["Melon", ...fruits, "Strawberry", "Orange"]
  .map((fruit) => ({ name: fruit.toUpperCase(), length: fruit.length }))
  .filter(({ length }) => length > 5)
  .toSorted();
/*
[
    {
        "name": "BANANA",
        "length": 6
    },
    {
        "name": "COCONUT",
        "length": 7
    },
    {
        "name": "STRAWBERRY",
        "length": 10
    },
    {
        "name": "ORANGE",
        "length": 6
    }
]
*/

자바스크립트 배열을 정렬할 때 사용되는 toSorted() 함수에 대해서는 관련 포스팅을 참고 바랍니다.

마치면서

지금까지 예제를 통해 자바스크립트 배열에 원소를 추가하는 대표적인 3가지 방법에 대해서 살펴보았습니다. 상황에 맞게 적절한 방법을 선택하셔서 보다 효율적으로 자바스크립트 배열을 다루실 수 있으셨으면 좋겠습니다. 자바스크립트 배열에 원소 제거하는 방법에 대해서는 별도 포스팅을 통해 다루겠습니다.