🎞

[JS] 배열


배열

배열은 순서가 있는 컬렉션을 저장하기 위한 자료구조다.

배열 선언

1let arr = [];
2arr = new Array();
3arr = ['초', '기', '화'];

배열 요소의 자료형엔 제약이 없다.

Pop/Push, Shift/Unshift

자바스크립트는 스택(stack), 큐(queue) 자료구조가 따로 제공되지 않지만, pushpop, shift 메서드를 통해 사용할 수 있다.

  • pop: 배열 끝 요소를 제거하고, 제거한 요소를 반환한다.
  • push: 배열 끝에 요소를 추가하고, 배열의 길이를 반환한다.
  • shift: 배열 앞 요소를 제거하고, 제거한 요소를 반환한다.
  • unshift: 배열 앞에 요소룰 추가하고, 배열의 길이를 반환한다.

pushunshift는 요소 여러개를 한 번에 추가할 수 있다.

1let sports = ["농구"];
2
3sports.push("축구", "야구");
4sports.unshift("수영", "탁구");
5
6console.log(sports);
7// -> ["수영", "탁구", "사과", "축구", "야구"]

이렇게 처음이나 끝에 요소를 더하거나 빼주는 연산을 제공하는 자료구조를 'Deque(Double ended queue)'라고 한다.

성능

pushpop은 빠르지만, shiftunshift는 느리다.

shift 연산은 아래 세 가지 동작을 모두 수행해야 한다.

  1. 인덱스가 0인 요소를 제거한다.
  2. 모든 요소를 왼쪽으로 옮긴다.
  3. length 속성 값을 갱신한다.

만약 배열에 요소가 많다면, 요소가 이동하는데 걸리는 시간이 길고 메모리 관련 연산도 많아진다. unshift도 이와 유사하다.

반면 poppush는 요소 이동을 수행하지 않기 때문에 수행속도가 빠르다.

배열의 내부 동작원리

배열은 '특별한 종류의 객체'다. 배열의 요소를 대괄호를 통해 접간하는 방식은 객체 문법에서 온 것이다.

객체이기 때문에 원하는 속성을 추가해도 문제가 발생하지 않고, 배열도 객체처럼 참조 복사된다.

자바스크립트 엔진은 배열의 요소를 인접한 메모리 공간에 차례로 저장해 연산속도를 높이고, 다른 최적화 기법들도 제공한다. 하지만, 개발자가 일반 객체처럼 다루면 최적화 기법들이 제대로 동작하지 않기 때문에 객체가 필요한 경우면 배열이 아닌 객체를 사용하자.

배열을 다루는 잘못된 방법:

  • 숫자가 아닌 값을 속성으로 사용
  • arr[0]arr[1000]만 추가하고 그 사이에 아무런 요소도 없는 경우
  • 요소를 역순으로 채우는 경우

반복자

  • for..of: 순회하면서 현재 요소의 '값'을 얻을 수 있다.
1let fruits = ["사과", "오렌지", "자두"];
2
3for (let fruit of fruits) {
4 console.log( fruit );
5}
6// -> 사과
7// -> 오렌지
8// -> 자두
  • for..in: 순회하면서 현재 요소의 '키'를 얻을 수 있다. 배열도 객체이기 때문에 사용할 수 있지만, 사용하지 않는 것이 좋다.

    for..in은 모든 속성을 대상으로 순회하기 때문에 키가 숫자가 아닌 속성도 대상에 포함될 수 있다. 브라우저나 기타 호스트 환경에서 사용되는 객체 중, 배열과 유사한 형태를 가지는 '유사 배열(array-like)' 객체가 있다. 유사 배열에 대해 for..in 연산을 하면 키가 숫자가 아닌 모든 속성(length 속성)도 순회의 대상으로 들어간다.

    그리고 for..in은 객체에 최적화 되어있기 때문에 배열에 사용하면 객체 대비 10~100배 느리다.

length 속성

배열에 무언가 조작하면 length 속성이 자동 갱신된다. length는 배열 내 요소의 개수가 아니라 가장 큰 인덱스에 1을 더한 값이다.

length는 개발자가 임의로 변경할 수 있다.

1let arr = [1, 2, 3, 4, 5];
2
3arr.length = 2;
4console.log(arr);
5// -> [1, 2]
6arr.length = 5;
7console.log(arr[3]);
8// undefined: 삭제된 기존 요소들이 복구되지 않는다.

참조:
ko.javascript.info