배열의 정확한 개념정리를 할 필요성을 느껴 정리해본다.
출처: https://ko.javascript.info/
배열 선언 및 출력
let arr = new Array();
let arr = [];
// 초기 값 선언
let fruits = ["사과", "오렌지", "자두"];
// 호출
fruits[0]; // 사과
// 배열 요소의 자료형엔 제약이 없음
let arr = [ '사과', { name: '이보라' }, true, function() { alert('안녕하세요.'); } ];
// 인덱스가 1인 요소(객체)의 name 프로퍼티를 출력합니다.
alert( arr[1].name ); // 이보라
pop,push 와 shift와 unshift
큐(queue)는 배열을 사용해 만들 수 있는 대표적인 자료구조로, 배열과 마찬가지로 순서가 있는 컬렉션을 저장하는 데 사용합니다. 큐에서 사용하는 주요 연산은 아래와 같습니다.
- push – 맨 끝에 요소를 추가합니다.
- shift – 제일 앞 요소를 꺼내 제거한 후 남아있는 요소들을 앞으로 밀어줍니다. 이렇게 하면 두 번째 요소가 첫 번째 요소가 됩니다.
배열엔 두 연산을 가능케 해주는 내장 메서드 push와 pop이 있습니다.
화면에 순차적으로 띄울 메시지를 비축해 놓을 자료 구조를 만들 때 큐를 사용하는 것처럼 큐는 실무에서 상당히 자주 쓰이는 자료구조입니다.
배열은 큐 이외에 스택(stack)이라 불리는 자료구조를 구현할 때도 쓰입니다.
스택에서 사용하는 연산은 아래와 같습니다.
- push – 요소를 스택 끝에 집어넣습니다.
- pop – 스택 끝 요소를 추출합니다.
자바스크립트 배열을 사용하면 큐와 스택 둘 다를 만들 수 있습니다. 이 자료구조들은 배열의 처음이나 끝에 요소를 더하거나 빼는 데 사용되죠.
배열의 내부 동작 원리
배열은 특별한 종류의 객체입니다. 배열 arr의 요소를 arr[0]처럼 대괄호를 사용해 접근하는 방식은 객체 문법에서 왔습니다. 다만 배열은 키가 숫자라는 점만 다릅니다.
이렇게 배열은 자바스크립트의 일곱 가지 원시 자료형에 해당하지 않고, 원시 자료형이 아닌 객체형에 속하기 때문에 객체처럼 동작합니다.
예시를 하나 살펴봅시다. 배열은 객체와 마찬가지로 참조를 통해 복사됩니다.
let fruits = ["바나나"]
let arr = fruits; // 참조를 복사함(두 변수가 같은 객체를 참조)
alert( arr === fruits ); // true
arr.push("배"); // 참조를 이용해 배열을 수정합니다.
alert( fruits ); // 바나나,배 - 요소가 두 개가 되었습니다.
배열을 배열답게 만들어주는 것은 특수 내부 표현방식입니다. 자바스크립트 엔진은 배열의 요소를 인접한 메모리 공간에 차례로 저장해 연산 속도를 높입니다. 이 방법 이외에도 배열 관련 연산을 더 빠르게 해주는 최적화 기법은 다양합니다.
그런데 개발자가 배열을 '순서가 있는 자료의 컬렉션’처럼 다루지 않고 일반 객체처럼 다루면 이런 기법들이 제대로 동작하지 않습니다.
let fruits = []; // 빈 배열을 하나 만듭니다.
fruits[99999] = 5; // 배열의 길이보다 훨씬 큰 숫자를 사용해 프로퍼티를 만듭니다.
fruits.age = 25; // 임의의 이름을 사용해 프로퍼티를 만듭니다.
배열은 객체이므로 예시처럼 프로퍼티를 추가해도 문제가 발생하지않는다.
그런데 이렇게 코드를 작성하면 자바스크립트 엔진이 배열을 일반 객체처럼 다루게 되어 배열특유의 이점이 사라진다.
잘못된 방법의 예는 다음과 같습니다.
- arr.test = 5 같이 숫자가 아닌 값을 프로퍼티 키로 사용하는 경우
- arr[0]과 arr[1000]만 추가하고 그사이에 아무런 요소도 없는 경우
- arr[1000], arr[999]같이 요소를 역순으로 채우는 경우
임의의 키를 사용해야 한다면 배열보단 일반 객체 {}가 적합한 자료구조일 확률이 높습니다.
성능
push와 pop은 빠르지만 shift와 unshift는 느립니다.
반복문
for 문
배열 순회시 인덱스 사용
for..of
현재 요소의 인덱스는 얻을 수 없고 값만 얻을 수 있음
for..in
배열은 객체형에 속하므로 for..in 사용 가능
- 모든 프로퍼티를 대상으로 순회한다. 키가 숫자가 아닌 프로퍼티도 순회 대상에 포함.
예를 들어 브라우저나 기타 호스트 환경에서 쓰이는 객체 중 유사 배열 객체엔 배열과 달리 키가 숫자형이 아닌 프로퍼티와 메서드가 있을 수 있다. ⇒ 필요 없는 프로퍼티들이 문제를 일으킬 가능성이 생김
- for..in반복문은 객체와 함께 사용할 때 최적화 되어 있어서 배열에 사용하면 객체 대비 10~100배 정도 느리다
- 배열엔 되도록 for..in 쓰지 말기
요약
- new Array(number)을 호출하면 길이가 number인 배열이 만들어지는데, 이 때 요소는 비어있습니다.
- length 프로퍼티는 배열의 길이를 나타내줍니다. 정확히는 숫자형 인덱스 중 가장 큰 값에 1을 더한 값입니다. 배열 메서드는 length 프로퍼티를 자동으로 조정해줍니다.
- length 값을 수동으로 줄이면 배열 끝이 잘립니다.
다음 연산을 사용하면 배열을 데큐처럼 사용할 수 있습니다.
- push(...items) – items를 배열 끝에 더해줍니다.
- pop() – 배열 끝 요소를 제거하고, 제거한 요소를 반환합니다.
- shift() – 배열 처음 요소를 제거하고, 제거한 요소를 반환합니다.
- unshift(...items) – items를 배열 처음에 더해줍니다.
아래 방법을 사용하면 모든 요소를 대상으로 반복 작업을 할 수 있습니다.
- for (let i=0; i<arr.length; i++) – 가장 빠른 방법이고 오래된 브라우저와도 호환됩니다.
- for (let item of arr) – 배열 요소에만 사용되는 모던한 문법입니다.
- for (let i in arr) – 배열엔 절대 사용하지 마세요.
'개발지식 > JavaScript' 카테고리의 다른 글
Promise (0) | 2022.04.26 |
---|---|
bind() 가 뭐야 (0) | 2022.04.18 |
함수형 메서드들의 오야지 reduce (0) | 2022.02.10 |
진수 변환 (0) | 2022.02.10 |
slice, splice (0) | 2022.02.02 |