Array.slice 자바스크립트 배열 자르기

원본: https://hackernoon.com/understanding-javascripts-array-slice-method

자바스크립트의 slice 메소드는 배열의 일부분을 얕은 복사본(shallow copy)으로 리턴합니다.

매개변수로는 start와 end 두 개의 값을 받으며 모든 배열에서 slice 메소드를 사용할 수 있습니다.

개발자 도구에서 다음의 간단한 예제를 확인해 보겠습니다:

let myArray = ['⚡️', '🔎', '🔑', '🔩'];

myArray.slice(2, 3);
slice 예제

이 메소드에는 start와 end 라는 두 가지 옵셔널 매개변수가 있습니다.

원하는 경우 둘다 사용할 수도 있고 start만 사용하거나 둘 다 사용하지 않을 수 있습니다. 따라서 다음의 코드는 모두 유효합니다:

let arrayOne = ['⚡️', '🔎', '🔑', '🔩'];
let arrayOneSlice = arrayOne.slice(2, 3);

let arrayTwo = ['⚡️', '🔎', '🔑', '🔩'];
let arrayTwoSlice = arrayTwo.slice(2);

let arrayThree = ['⚡️', '🔎', '🔑', '🔩'];
let arrayThreeSlice = arrayThree.slice();
slice 예제

slice 매개변수

start

이 매개변수는 리턴 값의 배열에 들어갈 항목의 인덱스 입니다.

예를 들어 2로 설정하면 이 메소드는 리턴할 배열 복사본을 인덱스 2에서 시작합니다.

음수를 사용하면 배열의 끝에서 부터 오프셋을 계산합니다. 다음의 예제를 확인해 보겠습니다:

let arrayOne = [ '⚡️', '🔎', '🔑', '🔩' ];
let arrayOneSlice = arrayOne.slice(-2);
let arrayOneSliceAgain = arrayOne.slice(-1);
slice start 매개변수 예제

end

이 매개변수는 리턴할 배열에서 제외할 첫 번째 요소입니다.

조금 혼란스러울 수 있는데 end는 결과 값에 포함할 마지막 항목이 아니라 제외할 첫 번째 항목입니다. slice 메소드 사용시 이 부분을 주의해야 합니다.

이 매개변수를 생략하면 다음 예제와 같이 배열의 끝 항목까지 리턴 값에 포함합니다:

let arrayOne = [ '⚡️', '🔎', '🔑', '🔩' ];
let arrayOneSlice = arrayOne.slice(2);
slice end 매개변수 예제

배열 길이보다 큰 값을 사용하면 이 메소드는 배열 끝까지만을 포함합니다. 또한 음수 값을 사용하면 배열 끝에서부터 오프셋으로 계산합니다.

예를 들어, (2, -1)을 입력하면 start는 인덱스 2가 되고 end는 -1이 됩니다.

let arrayTwo = [ '⚡️', '🔎', '🔑', '🔩' ];
let arrayTwoSlice = arrayTwo.slice(2, -1);
let arrayTwoSliceAgain = arrayTwo.slice(1, -1);
음수 매개변수 예제

slice 배열 복사

이 메소드는 원본 배열을 변경하지 않는 대신 새로운 얕은 복사본(shallow copy)을 만듭니다. 따라서 기존 배열의 항목이 계속 유지가 됩니다.

console.log() 메소드를 사용하여 변수의 값을 출력하면 다음과 같은 결과를 볼 수 있습니다.

let arrayOne = [ '⚡️', '🔎', '🔑', '🔩' ];
let arrayOneSlice = arrayOne.slice(2, 3);  

console.log(arrayOne);
console.log(arrayOneSlice);

이는 리턴 값으로 얕은 복사본을 만들기 때문에 때로는 배열 데이터를 복사하는데 사용할 수도 있습니다.

예를 들어 매개변수를 전달하지 않으면 메모리에 동일한 참조를 가지는 동일한 배열을 생성합니다.

let arrayOne = [ '⚡️', '🔎', '🔑', '🔩' ];
let arrayOneSlice = arrayOne.slice();

arrayOneSlice[2] = '⚡️'
console.log(arrayOne);
console.log(arrayOneSlice);
slice 복사 예제

이는 일부 시나리오에서는 유용하게 사용할 수 있습니다.

하지만 이 방법은 얕은 복사본을 만들기 때문에 배열의 항목이 객체인 경우 상황이 약간 혼란스러워 집니다.

다음 예제를 확인해 보겠습니다:

let arrayOne = [ { items: [ '⚡️', '🔎', '🔑', '🔩' ]}, '👨‍💻', '😄', '🐔' ];

위 예제 코드의 배열에는 객체가 포함되어 있습니다.

앞선 방법을 통해 이 배열의 복사본을 만든 다음 항목을 업데이트해 보겠습니다.

let arrayOne = [ { items: [ '⚡️', '🔎', '🔑', '🔩' ]}, '👨‍💻', '😄', '🐔' ];
let arrayOneSlice = arrayOne.slice(0, 2);

arrayOneSlice[0].items = [ '🔎' ];
arrayOneSlice[1] = '🔎';

console.log(arrayOne);
console.log(arrayOneSlice);
shallow copy 예제

위의 결과에서 보이는 바와 같이 arrayOneSlice의 항목을 변경했는데 arrayOne과 arrayOneSlice 배열 모두가 변경되었습니다.

이전의 예제 까지는 복사한 배열의 값만 변경되었는데 이번에는 모두가 변경되었습니다. 이는 얕은 복사를 했기 때문에 객체 자체를 복사하지 않고 객체의 참조만 복사했기 때문입니다. 이를 해결하려면 deep copy를 해야합니다.

정리

자바스크립트의 slice 메소드는 원본 배열을 바탕으로 shallow copy를 만들 때 유용하게 사용할 수 있습니다.

또한 제한된 범위내에서 독립적 업데이트를 할 수 있는 복사본을 만들 수 있습니다.

관련 글