배열(array)
은 어느 프로그래밍 언어에나 존재하는 자료구조이다.
JavaScript를 공부하던 중, 우연히 배열이 배열이 아니라는 이야기를 듣게 되었다.
따라서, 해당 글에서는 JavaScript에서 배열(array)에 대해 알아보고 알고 있던 배열과 다른 점을 알아보고자 한다.
자료구조에서 말하는 배열(array)은 동일한 크기의 메모리 공간이 빈틈없이 연속적으로 나열된 자료구조이다. 우리가 통상적으로 알고있는 이 배열을 밀집 배열(dense array)
이라고 한다.
위의 그림과 같이 일반적인 배열은 각 요소가 동일한 데이터 크기를 가지며, 빈틈없이 연속적으로 이어져 있다.
결론부터 말하자면, 자바스크립트의 배열은 배열이 아닌 객체이다. 더 정확하게는 일반적인 배열의 동작을 흉내 낸 특수한 객체이다.
자바스크립트에서 배열은 요소를 위한 각각의 메모리 공간은 동일한 크기를 갖지 않아도 되며, 연속적으로 이어져 있지 않을 수도 있다. 이러한 배열을 희소 배열(sparse array)
라고 한다.
const arr = [1, 2, 3];
console.log(typeof arr);
console.log(arr.constructor === Array); // true
console.log(Object.getPrototypeOf(arr) === Array.prototype); // true
위의 코드의 결과를 보면 알 수 있듯이 자바스크립트에서의 배열은 객체이다. 그렇다면 일반 객체와는 어떠한 차이가 있을까?
구분 | 객체 | 배열 |
---|---|---|
구조 | 프로퍼티 키와 프로퍼티 값 | 인덱스와 요소 |
값의 참조 | 프로퍼티 키 | 인덱스 |
값의 순서 | X | O |
length 프로퍼티 | X | O |
일반 객체와 배열을 구분하는 가장 명확한 차이는 값의 순서
와 length 프로퍼티
이다.
아래의 코드를 보자.
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: false }
}
*/
위의 코드의 결과처럼 자바스크립트 배열은 인덱스를 나타내는 문자열을 프로퍼티 key
로 가지며, length 프로퍼티를 갖는 특수한 객체다.
자바스크립트 배열의 요소는 사실 value
값이다.
자바스크립트에서는 모든 값이 객체의 프로퍼티 값이 될 수 있으므로 어떠한 타입의 값이라도 배열의 요소가 될 수 있다.
length 프로퍼티는 배열의 길이를 나타내는 0 이상의 정수를 값으로 갖는다.
const arr = [1, 2, 3];
console.log(arr.length); // 3
arr.push(4);
console.log(arr.length); // 4
arr.pop();
console.log(arr.length); // 3
length 프로퍼티에 임의의 값을 할당할 수도 있다.
const arr = [1, 2, 3, 4, 5];
arr.length = 3;
console.log(arr); // [1, 2, 3]
const arr = [1, 2];
arr.length = 4;
console.log(arr.length); // 4
console.log(arr); // [ 1, 2, <2 empty items> ]
위의 코드에 출력 결과에서 확인할 수 있는 empty items
는 실제로 추가가 되지는 않는다.
현재 length 프로퍼티 값보다 큰 숫자를 할당하게 되면 length는 변경되지만 실제 배열에는 아무 변화가 없다.
console.log(Object.getOwnPropertyDescriptors(arr));
/*
{
'0': { value: 1, writable: true, enumerable: true, configurable: true },
'1': { value: 2, writable: true, enumerable: true, configurable: true },
length: { value: 4, writable: true, enumerable: false, configurable: false }
}
*/
위의 코드의 결과를 보면 값이 없는 요소를 위해 메모리 공간을 확보하지 않은 것을 확인할 수 있다.
이처럼 배열의 요소가 연속적으로 위치하지 않고 일부가 비어 있는 배열을 희소 배열
이라고 한다.
자바스크립트 코드를 작성하다가 해당 변수가 배열인지 아닌지 체크해야할 때가 있다.
위에서 언급을 했지만 자바스크립트에서는 배열은 객체로 만들어져 있기 때문에 보통 사용하는 typeof
로는 배열인지 알 수가 없다.
따라서, 자바스크립트에서는 Array.isArray()
라는 배열인지 체크하는 메서드를 제공한다.
const arr = [1, 2, 3];
console.log(typeof arr); // object
console.log(Array.isArray(arr)); // true
TCPschool - 배열
MDN - Array
MDN - Array.isArray()
모던자바스크립트 - array
잘 배워갑니다~