자바스크립트 배열은 인덱스
를 프로퍼티 키로 갖으며 length
프로퍼티를 갖는 특수한 객체이다.
자바스크립트 배열은 해시 테이블로 구현된 객체이므로 인덱스로 배열 요소에 접근하는 경우, 일반적인 배열보다 성능적인 면에서 느릴 수 밖에 없는 구조적인 단점을 갖는다. 하지만 특정 요소를 탐색하거나 요소를 삽입 또는 삭제하는 경우에는 일반적인 배열보다 빠른 성능을 기대할 수 있다.
아래와 같이 두 가지 방법이 있다.
const arr = new Array(5); // length가 5인 빈 배열을 생성한다.
console.log(arr) // (5) [empty × 5]
const arr2 = Array.from({ length:5 }); // length가 5인 유사 배열 객체를 변환한다
console.log(arr2) // (5) [undefined, undefined, undefined, undefined, undefined]
유사 배열 객체(array-like object) 또는 이터러블 객체(iterable object)를 변환하여 새로운 배열을 생성한다.
// 유사 배열 객체를 새로운 배열을 변환하여 반환한다.
const arr1 = Array.from({ length: 2, 0: 'a', 1: 'b' });
console.log(arr2); // [ 'a', 'b' ]
// Array.from의 두번째 매개변수에게 배열의 모든 요소에 대해 호출할 함수를 전달할 수 있다.
// 이 함수는 첫번째 매개변수에게 전달된 인수로 생성된 배열의 모든 요소를 인수로 전달받아 호출된다.
const arr3 = Array.from({ length: 5 }, function (v, i) { return i; });
console.log(arr3); // [ 0, 1, 2, 3, 4 ]
유사 배열 객체
: 배열처럼 보이지만 사실 key가 숫자이고 length 값을 가지고 있는 객체를 말한다
또한, 리액트에서 컴포넌트를 반복할때 사용된다.
// + 버튼을 클릭한 횟수 만큼 컴포넌트 반복 렌더하기
// useState
const [count, setCount] = useState(0);
// 버튼 컴포넌트
<Button onClick={() => setCount(p => p + 1)}>+</Button>
// 추가 하기 버튼을 클릭한 만큼 Row 컴포넌트 반복하기
{Array.from({length:count}).map((_,i) => (
<div key={i}>
<Row/>
</div>
)}
const arr1 = [1, 2];
const arr2 = [3, 4];
// 배열 arr2를 원본 배열 arr1의 마지막 요소로 추가한 새로운 배열을 반환
// 인수로 전달한 값이 배열인 경우, 배열을 해체하여 새로운 배열의 요소로 추가한다.
let result = arr1.concat(arr2);
console.log(result); // [1, 2, 3, 4]
console.log(arr1) // [1, 2]
const arr1 = [1, 2];
const arr2 = [3, 4];
// 스프레드 연산자를 이용하여 새로운 배열을 반환
const combined = [...arr1, ...arr2];
console.log(combined); // [1, 2, 3, 4]
console.log(arr1); // [1, 2]
const arr1 = [1, 2];
const arr2 = [3, 4];
// reduce 메서드를 사용하여 arr2의 각 요소를 arr1에 합치기
const combined = arr2.reduce((accumulator, currentValue) => {
accumulator.push(currentValue);
return accumulator;
}, arr1); // arr1을 초기값으로 설정
console.log(combined); // [1, 2, 3, 4]
console.log(arr1); // [1, 2]
push() 메서드는 원본 배열을 변경할뿐만 아니라 성능면에서도 좋지 않다.
따라서 push() 메서드를 사용하는 것보단 스프레드 연산자
를 통해 원본 배열을 유지하거나, 원본 배열에 새로운 값을 추가할 땐 아래와 같은 방식으로 추가하는 것이 좋다.
const arr = [1, 2];
// arr.push(3)와 동일한 처리를 한다. 이 방법이 push 메소드보다 빠르다.
arr[arr.length] = 3;
console.log(arr); // [1, 2, 3]
인자로 지정된 배열의 부분을 복사하여 반환한다. 원본 배열은 변경되지 않는다.
Array.prototype.slice(start=0, end=this.length)
const items = ['a', 'b', 'c'];
// items[0]부터 items[1] 이전(items[1] 미포함)까지 반환
let res = items.slice(0, 1);
console.log(res); // [ 'a' ]
// items[1]부터 이후의 모든 요소 반환
res = items.slice(1);
console.log(res); // [ 'b', 'c' ]
// 인자가 음수인 경우 배열의 끝에서 요소를 반환
res = items.slice(-1);
console.log(res); // [ 'c' ]
// 원본은 변경되지 않는다.
console.log(items); // [ 'a', 'b', 'c' ]
slice 메소드에 인자를 전달하지 않으면 원본 배열의 복사본을 생성하여 반환한다. 이때 원본 배열의 각 요소를 얕은 복사
(shallow copy)하여 새로운 복사본을 생성한다.
const arr = [1, 2, 3];
// 원본 배열 arr의 새로운 복사본을 생성한다.
const copy = arr.slice();
console.log(copy, copy === arr); // [ 1, 2, 3 ] false
console.log(copy[0] === arr[0]) // true
기존의 배열의 요소를 제거하고 그 위치에 새로운 요소를 추가한다. 배열 중간에 새로운 요소를 추가할 때도 사용된다. splice() 메서드는 원본 배열이 변경된다.
Array.prototype.splice(start: number, deleteCount=this.length-start, …items: T[])
deleteCount
: 시작 위치(start)부터 제거할 요소의 수이다. deleteCount가 0인 경우, 아무런 요소도 제거되지 않는다. (옵션)
items
: 삭제한 위치에 추가될 요소들이다. 만약 아무런 요소도 지정하지 않을 경우, 삭제만 한다. (옵션)
const items1 = [1, 2, 3, 4];
// items[1]부터 2개의 요소를 제거하고 제거된 요소를 배열로 반환
const res1 = items1.splice(1, 2);
// 원본 배열이 변경된다.
console.log(items1); // [ 1, 4 ]
// 제거한 요소가 배열로 반환된다.
console.log(res1); // [ 2, 3 ]
const items2 = [1, 2, 3, 4];
// items[1]부터 2개의 요소를 제거하고 그자리에 새로운 요소를 추가한다. 제거된 요소가 반환된다.
const res2 = items.splice(1, 2, 20, 30);
// 원본 배열이 변경된다.
console.log(items2); // [ 1, 20, 30, 4 ]
// 제거한 요소가 배열로 반환된다.
console.log(res2); // [ 2, 3 ]