배열
작성일 : 2024.10.01
- 배열 : 여러개의 값을 순차적으로 나열한 자료구조
- 요소 : 배열이 가지고 있는 값
- 인덱스 : 요소의 위치를 나타내는 0 이상의 정수
- 배열은 객체 타입이다
- 배열은 배열 리터럴, Array 생성자 함수, Array.of, Array.from 메서드로 생성 가능
- 배열의 생성자 함수 : Array
- 배열의 프로토타입 객체 : Array.prototype
- 일반 객체와 배열을 구분하는 가장 명확한 차이는 "값의 순서"와 "length 프로퍼티"
| 구분 | 객체 | 배열 |
|---|---|---|
| 구조 | 프로퍼티 키와 프로퍼티 값 | 인덱스와 요소 |
| 값의 참조 | 프로퍼티 키 | 인덱스 |
| 값의 순서 | X | O |
| length 프로퍼티 | X | O |
JS 배열은 배열이 아니다
- 밀집 배열 : 동일한 크기의 메모리 공간이 빈틈없이 연속적으로 나열된 자료구조
- 희소배열 : 배열의 요소가 연속적으로 이어져 있지 않는 배열
- 검색대상요소의 메모리 주소 = 배열의 시작 메모리 주소 + 인덱스 * 요소의 바이트 수
- JS의 배열: 일반적인 배열의 동작을 흉내낸 특수한 객체
- 일반적인 배열은 인덱스로 요소에 빠르게 접근할 수 있다. 하지만 요소를 삽입 또는 삭제하는 경우에 비효율적이다
- JS 배열은 해시 테이블로 구현된 객체
- 인덱스로 요소에 접근하는 경우, 일반적인 배열보다 성능적인 면에서 느릴 수 밖에 없는 구조적인 단점이 있다.
- 요소를 삽입 또는 삭제하는 경우에는 일반적인 배열보다 빠른 성능을 기대할 수 있다는 장점을 가지고 있다.
length 프로퍼티와 희소 배열
-
length 프로퍼티 : 배열의 길이를 나타내는 0 이상의 정수
-
length 프로퍼티의 값은 배열에 요소를 추가하거나 삭제하면 자동 갱신된다
-
length 값은 배열의 길이를 바탕으로 결정되지만 임의의 숫자 값을 명시적으로 할당 가능
-
희소 배열은 length와 배열 요소의 개수가 일치하지 않는다.
-
희소 배열의 length는 희소 배열의 실제 요소 개수보다 언제나 크다.
-
배열에는 같은 타입의 요소를 연속적으로 위치시키는 것이 최선이다.
배열 생성
배열 리터럴
const arr = [1,2,3];
const arr2 = [];
const arr3 = [1, ,3];
Array 생성자 함수
- Array 생성자 함수는 전달된 인수의 개수에 따라 다르게 동작하므로 주의가 필요하다
- 배열은 요소를 최대 4,294,967,295개 가질 수 있다
- 전달된 인수가 없는 경우 빈 배열을 생성
- 전달된 인수가 2개 이상이거나 숫자가 아닌 경우 인수를 요소로 갖는 배열을 생성
- Array 생성자 함수는 new 연산자와 함께 호출하지 않더라도, 배열을 생성하는 생성자 함수가 동작
const arr = new Array(10);
Array.of
- Array.of 메서드 : 전달된 인수를 요소로 갖는 배열을 생성
Array.of(1);
Array.of(1,2,3);
Array.of('string');
Array.from
- Array.from 메서드 : 유사 배열 객체 또는 이터러블 객체를 인수로 전달받아 배열로 변환해서 반환
- 유사 배열 객체 : 배열처럼 인덱스로 프로퍼티 값에 접근할 수 있고, length 프로퍼티를 갖는 객체
Array.from({length:2, 0:'a', 1:'b'}); // -> ['a','b']
Array.from('Hello'); // -> ['H','e','l','l','o']
Array.from({length:2}); // -> [undefined, undefined]
Array.from({length:2, (_, i) => i}); //-> [0,1]
배열 요소의 참조
- 배열의 요소를 참조할 때는 대괄호 표기법을 사용
배열 요소의 추가와 갱신
- 존재하지 않는 인덱스를 사용해 값을 할당하면 새로운 요소가 추가됨
- 인덱스로 요소에 접근하여 명시적으로 값을 할당하지 않는 요소는 생성되지 않는다는 것에 주의
- 정수 이외의 값을 인덱스처럼 사용하면 요소가 생성되는 것이 아니라 프로퍼티가 생성됨
배열 요소의 삭제
- 배열은 객체이기 때문에 배열의 특정 요소를 삭제하기 위해 delete 연산자를 사용
- delete를 사용할 시 희소배열이 만들 수 있으므로 delete 연산자는 사용하지 않는 것이 좋다
- 특정요소를 완전히 삭제하려면, Array.prototype.splice 메서드를 사용
const arr = [1,2,3];
arr.splice(1,1);
console.log(arr); // [1,3]
배열 메서드
- 배열 메서드에 2가지 패턴이 존재
- 원본 배열을 직접 변경하는 메서드
- 원본 배열을 직접 변경하지 않고 새로운 배열을 생성하여 반환하는 메서드
Array.isArray
- isArray : 전달된 인수가 배열이면 true, 배열이 아니면 false 반환
Array.isArray([])
Array.prototype.indexOf
- indexOf : 원본 배열에서 인수로 전달된 요소를 검색하여 인덱스 반환
- 원본 배열에 인수로 전달한 요소와 중복되는 요소가 여러 개 있으면, 첫 번째로 검색된 요소의 인덱스를 반환한다.
- 원본 배열에 인수로 전달할 요소가 존재하지 않으면 -1을 반환한다.
const arr = [1,2,3,4];
arr.indexOf(2);
arr.indexOf(1,2); //2번째부터 검색
- indexOf 메서드보다 ES7에 도입된 Array.prototype.includes 메서드를 사용하면 가독성이 향상됨
Array.prototype.push
- push : 인수로 전달받은 모든 값을 원본 배열의 마지막 요소로 추가하고 변경된 length 값을 반환