본문 바로가기

JavaScript

[Modern JavaScript Deep Dive] Array

Array

배열이란 여러개의 값을 순차적으로 나열한 자료구조입니다.

배열이 가지고 있는 값을 요소 (Element)라고 부릅니다. JavaScript의 모든 값은 배열의 요소가 될 수 있습니다. 즉, 원시값은 물론, 객체, 함수, 배열등 자바스크립트에서 값으로 인정하는 모든 것은 배열의 요소가 될 수 있습니다.

배열의 요소는 배열에서 자신의 위치를 나타내는 0 이상의 정수인 인덱스를 갖습니다.

배열은 index와 length 프로퍼티를 갖기 때문에 for문을 통해 순차적으로 접근할 수 있습니다.

자바스크립트에 배열이라는 타입은 존재하지 않습니다. 배열은 객체 타입입니다.

typeof arr // object

배열은 배열 리터럴, Array 생성자 함수, Array.of, Array.from 메서드로 생성할 수 있습니다. 배열의 생성자 함수는 Array 이며, 배열의 프로토타입 객체는 Array.prototype 입니다. Array.prototype은 배열을 위한 빌트인 메서드를 제공합니다.

const arr = [ 1,2,3,4]
arr.constructor === Array // true
Object.getPrototypeOf(arr) === Array.prototype // true

일반 객체와 배열을 구분하는 가장 명확한 차이는 값의 순서와 length 프로퍼티입니다.

자바스크립트 배열은 배열이 아니다.

자료구조에서 말하는 배열은 동일한 크기의 메모리 공간이 빈틈없이 연속적으로 나열된 자료구조를 말합니다. 이러한 배열을 밀집 배열이라고 합니다. 원래 배열은 인덱스를 통해 단한번의 연산으로 원소에 접근할 수 있습니다. (O(1)) 이는 매우 효율적이고 빠르게 동작합니다.

자바스크립트의 배열은 일반 배열과 다릅니다. 즉 배열의 요소를 위한 각각의 메모리 공간은 동일한 크기를 갖지 않아도 되며, 연속적으로 이어져 있지 않을 수도 있습니다. 연속적으로 이어져 있지 않은 배열을 희소배열(sparse array)라고 합니다. 자바스크립트의 배열은 일반적인 배열의 동작을 흉내낸 특수한 객체입니다.

console.log(Object.getOwnPropertyDescriptors([1,2,3]));
/*
{
    '0' : { value : 1, writable: true, enumerable: true, configurable: true},
    '1' : { value : 2, writable: true, enumerable: true, configurable: true},
    '2' : { value : 3, writable: true, enumerable: true, configurable: true},
    length : {value : 3, writable: true, enumerable: false, configurable: fasle},
}
*/

이처럼 자바스크립트 배열은 인덱스를 나타내는 문자열을 키로 가지며 length 프로퍼티를 갖는 특수한 객체입니다. 자바스크립트에서 사용할 수 있는 모든 값은 객체의 프로퍼티 값이 될 수 있으므로 어떤 타입의 값이라도 배열의 요소가 될 수 있다.

const arr = [ 'hyunjin' , 10 , true, null, undefined, NaN, Infinity, [], {}, function() {} ] 
  • 일반적인 배열은 인덱스로 요소에 빠르게 접근할 수 있다. 하지만 특정 요소를 검색하거나 요소를 삽입또는 삭제하는 경우에는 효율적이지 않다. dense
  • 자바스크립트 배열은 해시 테이블로 구현된 객체이므로 인덱스로 요소에 접근하는 경우 일반적인 배열보다 성능적인 면에서 느릴 수 밖에 없는 구조를 갖는다. 하지만 특정 요소를 검색하거나 요소를 삽입또는 삭제하는 경우에는 일반적인 배열보다 빠른 성능을 기대할 수 있다.

자바스크립트의 배열은 인덱스로 접근하는 경우의 성능대신 특정 요소를 탐색하거나 배열 요소를 삽입 또는 삭제하는 경우의 성능을 선택한 것입니다.

인덱스로 배열 요소에 접근할 때 일반적인 배열보다 느릴 수 밖에 없는 구조적인 단점을 보완하기 위해 대부분의 모던 자바스크립트 엔진은 배열을 일반 객체와 구별해서 좀더 배열처럼 동작하도록 최적화하여 구현했습니다. 다음과 같이 일반객체와 배열의 성능을 테스트해보면 일반객체보다 약 2배정도 빠르다는 것을 알 수 있습니다.

const arr = [];
console.time('Array Performance Test');
for (let i = 0 ;i <10000000; i++) {
    arr[i] = i;
}
console.timeEnd('Array Performance Test');
// 약 340ms
const obj = {}
console.time('Object Performance Test');
for (let i = 0 ; i< 10000000; i++) {
    obj[i] = i;
}
console.timeEnd('Object Performance Test');
// 약 600ms

length 프로퍼티와 희소 배열

가장 작은 length 프로퍼티의 값은 0 가장 큰 length 프로퍼티의 값은 2의 32승 - 1 즉 인덱스는 2의 32승 -2 입니다.

length 프로퍼티의 값은 배열에 요소를 추가하거나 삭제하면 자동으로 갱신됩니다.

'JavaScript' 카테고리의 다른 글

[JavaScript] fetch  (0) 2022.03.04
[Core JavaScript] class  (0) 2022.03.04
[Modern JavaScript Deep Dive] Iterable  (0) 2022.03.02
[JavaScript] CustomEvent  (0) 2022.03.01
defer & async in script tag  (0) 2022.03.01