study/js-deepdive
[JS-Deepdive] 27장 배열 (Array)
온몸비틀기
2024. 9. 18. 14:30
27장 배열 (Array)
01. 배열이란?
- 배열은 여러 개의 값을 순차적으로 나열한 자료구조다.
- 배열이 가지고 있는 값을 요소(element)라고 부른다.
- 배열에서 자신의 위치를 나타내는 0이상의 정수인 index를 갖는다.
- 배열은 요소의 개수, 길이를 나타내는 length 프로퍼티를 갖는다.
- 배열은 객체지만 일반 객체와는 구별되는 독특한 특징이 있다.
구분 객체 배열 구조 프로퍼티 키와 프로퍼티 값 인덱스와 요소 값의 참조 프로퍼티 키 인덱스 값의 순서 ✕ ○ length 프로퍼티 ✕ ○ - 일반 객체와 배열을 구분하는 가장 명확한 차이는 값의 순서와length 프로퍼티다.- 인덱스로 표현하는 값의 순서와 length 프로퍼티를 갖는 배열은 반복문을 통해 순차적으로 값에 접근하기 적합한 자료구조다. - 배열의 장점은 처음부터 순차적으로 요소에 접근할 수도 있고, 마지막부터 역순으로 요소에 접근할 수도 있으며, 특정 위치부터 순차적으로 요소에 접근할 수도 있다는 것이다.
- 이는 배열이 인덱스, 값의 순서와 length 프로퍼티를 갖기 때문에 가능한 것이다.
02. 자바스크립트 배열은 배열이 아니다
- 자료구조에서 말하는 배열은 동일한 크기의 메모리 공간이 빈틈없이 연속적으로 나열된 자료구조를 말한다.
- 배열의 요소는 하나의 데이터 타입으로 통일되어 있으며 서로 연속적으로 인접해 있다. (밀집 배열)
- 자바스크립트의 배열은 자료구조에서 말하는 일반적인 의미의 배열과 다르다.
- 배열의 요소를 위한 각가의 메모리 공간은 동일한 크기로 갖지 않아도 되며, 연속적으로 이어져 있지 않을 수도 있다.
- 배열의 요소가 연속적으로 이어져 있지 않는 배열을 희소 배열이라 한다.
- 자바스크립트의 배열은 일반적인 배열의 동작을 흉내 낸 특수한 객체다
- 자바스크립트 배열은 인덱스를 나타내는 문자열을 프로퍼티 키로 가지며, length 프로퍼티를 갖는 특수한 객체다.
- 자바스크립트 배열의 요소는 사실 프로퍼티 값이다.
- 자바스크립트에서 사용할 수 있는 모든 값은 객체의 프로퍼티 값이 될 수 있으므로 어떤 타입의 값이라도 배열의 요소가 될 수 있다.
일반 개열과 자바스크립트 배열의 장단점을 정리해보자
- 일반적인 배열은 인덱스로 요소에 빠르게 접근할 수 있다. 하지만 요소를 삽입 또는 삭제하는 경우에는 효율적이지 않다.
- 자바스크립트 배열은 해시 테이블로 구현된 객체이므로 인텍스로 요소에 접근하는 경우 일반적인 배열보다 성능적인 면에서 느릴수밖에 없는 구조적인 단점이 있다. 하지만 요소를 삽입 또는 삭제하는 경우네는 일반적인 배열보다 따른 성능을 기대할 수 있다.
03. length 프로퍼티와 희소 배열
- length 프로퍼티는 요소의 개수, 즉 배열의 길이를 나타내는 0 이상의 정수를 값으로 갖는다.
- 프로퍼티의 값보다 작은 임의의 숫자 값을 할당하면 배열의 길이가 줄어든다.
- 자바스크립트는 희소 배열을 문법적으로 허용한다.
- 배열의 요소가 연속적으로 위치하지 않고 일부가 비어 있는 배열을 희소 배열이라 한다.
- 희소 배열은 length와 배열 요소의 개수가 일치하지 않는다.
- 희소 배열의 length는 희소 배열의 실제 요소 개수보다 언제나 크다.
- 하지만 배열을 생성할 경우에는 희소 배열을 생성하지 않도록 주의해야 한다. 배열에는 같은 타입의 요소를 연속적으로 위치시키는것이 최선이다.
const arr = [1, 2, 3, 4, 5];
// 현재 length 프로퍼티 값인 5보다 작은 숫자 값 3을 length 프로퍼티에 할당
arr.length = 3;
// 배열의 길이가 5에서 3으로 줄어든다.
console.log(arr); // [1, 2, 3]
04. 배열 생성
04-01. 배열 리터럴
- 배열 리터럴은 0개 이상의 요소를 쉼표로 구분하여 대괄호로 묶는다.
- 객체 리터럴과 달리 프로퍼티 키가 없고 값만 존재한다.
04-02. Array 생성자 함수
- Array 생성자 함수를 통해 배열을 생성할 수도 있다.
04-03. Array.of
- ES6에서 도입된
Array.of메서드는 전달된 인수를 요소로 갖는 배열을 생성한다.- Array 생성자 함수와는 다르게 전달된 인수가 1개이고 숫자이더라도 인수를 요소로 갖는 배열을 생성한다.
// 전달된 인수가 1개이고 숫자이더라도 인수를 요소로 갖는 배열을 생성한다.
Array.of(1); // [1]
Array.of(1, 2, 3); // [1, 2, 3]
Array.of("string"); // ["string"]
04-04. Array.from
- ES6에서 도입된 Array.from 메서드는 유사 배열 객체 또는 이터러블 객체를 인수로 전달받아 배열로 변환하여 반환한다.
유사 배열 객체와 이터러블 객체
유사 배열 객체
- 유사 배열 객체는 마치 배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고 length 프로퍼티를 갖는 객체를 말한다.
- 유사 배열 객체는 마치 배열처럼 for 문으로 순회할 수도 있다.
이터러블 객체
- 이터러블 객체는
Symbol.iterator메서드를 구현하여 for...of 문으로 순회할 수 있으며, 스프레드 문법과 배열 디스트럭처링 할당의 대상으로 사용할 수 있는 객체를 말한다.
05. 배열 요소의 참조
- 배열의 요소를 참조할 때에는 대괄호 표기법을 사용한다.
- 대괄호 안에는 인덱스가 와야 한다.
- 존재하지 않는 요소에 접근하면
undefined가 반환된다.
06. 배열 요소의 추가와 갱신
- 객체에 프로퍼티를 동적으로 추가할 수 있는 것처럼 배열에도 요소를 동적으로 추가할 수 있다.
- 존재하지 않는 인덱스를 사용해 값을 할당하면 새로운 요소가 추가된다.
- 이때 length 프로퍼티 값은 자동 갱신된다.
- 만약 현재 배열의 length 프로퍼티 값보다 큰 인덱스로 새로운 요소를 추가하면 희소 배열이 된다.
- 이미 요소가 존재하는 요소에 값을 재할당하면 요소값이 갱신된다.
07. 배열 요소의 삭제
- 배열은 사실 객체이기 때문에 배열의 특정 요소를 삭제하기 위해 delete 연산자를 사용할 수 있다.
- 하지만 프로퍼티 키만을 삭제하고 length 프로퍼티의 값은 변하지 않아 희소 배열이 만들어지므로 사용하지 않는것이 좋다.
- 희소배열을 만들지 않으면서 배열의 특정 요소를 완전히 삭제하려면
Array.prototype.splice메서드를 사용한다.