Javascript Cookbook

기존 배열의 부분 집합으로 새 배열 작성하기

문제

기존 배열이 일부로 새 배열을 만들고 싶다. 배열 원소가 객체라면 두 배열이 계속 동기화될 수 있도록 해야 한다.

해결

Array 객체의 slice 메서드를 사용하면 주어진 범위의 원소를 기반으로 새 배열을 만들 수 있다.

var origArray = new Array();
origArray[0] = new Array("one", "two");
origArray[1] = new Array("three", "four");
origArray[2] = new Array("five", "six");
origArray[3] = new Array("seven", "eight");

//slice를 사용하여 새 배열 작성
var newArray = origArray.slice(1,3);

설명

slice 메서드의 인수로 복사할 원소의 시작 인덱스와 끝 인덱스를 전달한다. 인덱스 값이 음수면 slice 메서드는 배열의 끝에서부터 작업한다.

복사할 원소가 문자열, 숫자, 불리언과 같은 리터럴 값이면 값 자체가 복사되기 때문에 이전 배열에서 값을 변경해도 새 배열에는 아무런 영향을 미치지 못하고, 반대로도 마찬가지 이다.

그러나 객체를 복사할 때는 slice를 사용했든 직접 변수를 할당했든 상관없이 참조로 복사되어 원래의 배열의 값이 변경되면 새로운 배열에도 값이 반영되고 반대로 새로운 배열의 값이 변경되면 원래의 배열에도 값이 반영된다.

아래의 코드는 slice 사용시 객체 동기화를 보여준다.

var origArray = new Array(4);
origArray[0] = new Array("one", "two");
origArray[1] = new Array("three", "four");
origArray[2] = new Array("five", "six");
origArray[3] = new Array("seven", "eight");

//slice를 사용하여 새 배열 작성
var newArray = origArray.slice(1,3);
alert(newArray);    //three,four,five,six 출력

//원본 수정
origArray[1][0] = "octopus";

//새로운 배열 출력
alert(newArray);    //octopus,four,five,six 출력

slice는 함수 인수를 배열로 변환할 때도 편리하게 사용할 수 있다.

function list() {
  return Array.prototype.slice.call(arguments);
}

list(1, 2, 3) // [1 ,2 3]

IE8은 slice를 지원하지 않으며 IE9부터는 slice 메서드를 지원한다.