자바스크립트의 배열은 객체이다
2분 읽기
JavaScript를 배우다 보면 분명 배열을 만들었는데 typeof는 이런 결과를 반환합니다.
typeof [] // 'object'내가 치명적인 버그를 발견한 건가 싶지만, 의도된 동작입니다. 이 글에서는 배열이 무엇인지, JavaScript가 배열을 어떻게 구현했는지, 그 결과로 어떤 특성이 생기는지 차례대로 살펴봅니다.
배열은 리스트 ADT의 구현체다링크를 제목에 복사
배열이 왜 객체인지 이해하려면, 먼저 배열이 무엇인지부터 짚고 넘어가야 합니다.
배열은 리스트 ADT(Abstract Data Type) 의 구현체 중 하나입니다. 리스트 ADT는 "유한한 길이의 순서를 가진 항목들을 저장하는 자료 구조"를 정의하는 명세로, 이를 구현하는 방식은 두 가지입니다.
배열로 구현한 리스트 (Array List)링크를 제목에 복사
- 메모리의 연속된 공간에 데이터를 저장합니다
- 인덱스로 원하는 요소에 즉시 접근할 수 있습니다 (O(1))
- 삽입·삭제 시 나머지 요소를 밀거나 당겨야 합니다 (O(n))
연결로 구현한 리스트 (Linked List)링크를 제목에 복사
- 데이터와 포인터를 가진 노드를 메모리 불연속 공간에 저장하고 연결합니다
- 특정 요소를 찾으려면 처음부터 순차 탐색해야 합니다 (O(n))
- 포인터만 바꾸면 되므로 삽입·삭제가 빠릅니다 (O(1))
C, Java 같은 정적 타입 언어의 배열은 전통적인 배열 리스트에 가깝습니다. 크기가 고정되고, 단일 타입만 저장하며, 연속된 메모리 주소에 할당됩니다. 그런데 JavaScript의 배열은 이와 다릅니다.
JavaScript 배열의 정체: 해시 테이블로 구현된 객체링크를 제목에 복사
JavaScript 배열은 전통적인 배열이 아닙니다.
typeof [] // 'object'
[] instanceof Object // true
[1, 2, 3]['0'] // 1 — 숫자가 아닌 문자열 키로 접근해도 동작합니다결국 JavaScript 배열은 해시 테이블로 구현된 특수한 객체입니다. 인덱스(0, 1, 2)가 문자열 키로 처리되고, length라는 특별한 프로퍼티를 추가로 갖습니다.
const arr = ['a', 'b', 'c']
// 내부적으로는 이런 구조와 유사합니다
{
'0': 'a',
'1': 'b',
'2': 'c',
length: 3,
}그래서 이런 일도 가능합니다.
const arr = [1, 2, 3]
arr.name = 'my array' // 일반 프로퍼티 추가 가능
console.log(arr.name) // 'my array'
console.log(arr.length) // 3 — name은 length에 포함되지 않습니다왜 이렇게 설계했을까요링크를 제목에 복사
JavaScript는 프로토타입 기반 언어입니다. 모든 값은 객체이거나 객체처럼 동작합니다. 배열도 이 철학을 따라 Array.prototype을 상속받는 객체로 설계됐습니다.
덕분에 배열은 map, filter, reduce 같은 메서드를 프로토타입 체인으로 사용할 수 있고, 동적으로 크기가 조정되며, 다양한 타입을 섞어 저장할 수 있습니다. 배열을 구현하는 방식은 언어의 성격과 철학에 맞게 최적화되는데, JavaScript는 그 중 유연함을 택한 셈입니다.
그렇다면 배열을 어떻게 구별하나요링크를 제목에 복사
typeof로는 배열과 일반 객체를 구분할 수 없습니다. 배열 여부를 판별할 땐 Array.isArray()를 사용합니다.
typeof [] // 'object' — 구분 불가
typeof {} // 'object'
Array.isArray([]) // true
Array.isArray({}) // falseinstanceof Array도 동작하지만, iframe처럼 다른 실행 컨텍스트를 넘나드는 상황에선 각자 다른 Array 생성자를 참조해 오작동할 수 있습니다. 그래서 Array.isArray()가 더 안전합니다.
정리하면링크를 제목에 복사
- JavaScript 배열은 해시 테이블로 구현된 특수한 객체입니다.
- 인덱스는 내부적으로 문자열 키로 처리되며,
length프로퍼티를 가집니다. typeof []가'object'를 반환하는 건 버그가 아니라 JavaScript의 설계입니다.- 배열 여부 판별에는
typeof대신Array.isArray()를 사용합니다. - 이 설계 덕분에 동적 크기 조정, 혼합 타입 저장, 메서드 상속이 가능합니다.
관련 글
자바스크립트로 구현하는 힙
힙(Heap) 자료구조의 개념과 Min Heap, Max Heap을 JavaScript와 TypeScript로 구현하는 방법을 정리합니다.
소수 구하기
소수 판별법과 소수를 구하는 알고리즘을 정리합니다.
[프로그래머스 Level 2] 미로 탈출
프로그래머스 미로 탈출을 BFS로 풀이합니다.
모든 글