-
[JavaScript] JS에서의 배열은 배열이 아니다?Programming Language/JavaScript 2022. 2. 5. 02:14
※본 포스팅은 개인 학습을 목적으로 작성된 것이므로 정확하지 않은 정보가 포함되어 있을 수 있음을 참고 부탁드립니다.
사실 알고리즘 문제를 풀며, '얕은복사 vs 깊은복사'에 대하여 찾아보다가 여기까지 왔다.
두 가지 복사에 대하여 구글링해서 몇가지 포스팅을 보고, 혹시 모던 자바스크립트 Deep Dive 책에도 설명이 나와있을까 해서 배열 부분을 뒤적거리다가 '자바스크립트에 배열이라는 타입은 존재하지 않고, 배열은 객체 타입'이라는 내용을 보았다.
??? : 지금까지 arr 혹은 array라고 이름을 지어줬고, [ ] 로 초기화해 줬는걸? 아무튼 위의 한 줄은 나에게 매우 흥미로운 주제였다.
그리고 그와 함께 나는 기본 없이 3개월간 자바스크립트를 사용하고 있었던 것인가..? 라는 생각도 들었다.
'얕은복사 vs 깊은복사'에 대한 포스팅은 추후에 진행하는걸로!
일단 책에 있는 내용을 보다가 궁금해서 console로 찍고, 직접 눈으로 확인하며 이해하려고 했다.
첫번째 라인: 배열 모양을 하고 있는 arr의 타입은? 👉 object(객체)
두번째 라인: arr의 생성자 함수는 Array 인가? 👉 true
세번째 라인: arr의 프로토타입 객체는 Array.prototype 인가? 👉 true
*참고로 마지막 undefined가 나오길래 크롬에서 console.log()를 찍어서 나오는걸까?하고 vscode로 가서 시도를 해보았다. vscode에서는 나오지 않았다. 왜 나오나 찾아봤는데, 자바스크립트에서는 함수 내부에서 return 하는 값이 없을 경우 undefined가 반환된다고 한다. 반환값을 console.log로 찍기 때문에 undefined가 중간에 찍히는 것이니 참고하면 좋을 것 같다. (왜 vscode에서는 안나올까? 궁금했지만, 길을 잃으면 안 되기에 돌아왔다...)
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/undefined#%EC%84%A4%EB%AA%85배열은 객체지만 일반 객체와는 구분이 있다고 하여 어떤 차이가 있는지 찾아봤다.
구분 객체 배열 구조 프로퍼티 키와 프로퍼티 값 인덱스와 요소 값의 참조 프로퍼티 키 인덱스 값의 순서 X O length 프로퍼티 X O 배열의 경우 인덱스의 순서대로 for문을 통해 배열의 길이만큼 반복할 수 있다.
접근 방법은 순차적, 역순, 원하는 위치부터 등 다양하고, 이것은 배열이 가진 값의 순서와 length 프로퍼티로 인하여 가능하다.
123456const arr = [1, 2, 3, 4];for(let i = 0; i < arr.length; i++) {console.log(i);}cs 위와 같이 배열과 일반 객체의 차이점을 제시한 이후 Deep Dive 책에서는 배열의 두 가지 종류에 대해서 언급한다.
여기서 저자는 '일반적인 의미의 배열' 이라는 언급을 했는데, 그렇다면 여기서 말하는 '일반적'이라는게 무엇일까?포인터에서 포기했지만, 그래도 제일 처음 배웠던게 C언어였고 강사님이 엑셀로 열심히 그려주셨던 메모리 주소들이 생각났다.C언어의 배열일 것 같다는 생각에 다시 C언어의 배열 vs 자바스크립트의 배열 폭풍 검색..
배열부터 정리하기엔 끝이 없을 것 같아서, 아주 잘 정리되어 있는 블로그를 가져왔다.
https://undefined.tistory.com/51) 밀집 배열
장점
- 자료구조에서 말하는 배열로, 동일한 크기의 메모리 공간이 빈틈없이 연속적으로 나열되어 있다.
- 배열의 요소는 하나의 데이터 타입으로 통일되어 있으며, 서로 연속적으로 인접해 있다.
- 빈틈X, 연속적 -> 인덱스를 통해 한 번의 연산으로 요소에 접근 가능하며, 시간 복잡도 O(1)로 매우 효율적이고 고속으로 동작한다.
직접 그리면서 C의 추억을 되새겨 보았다. 위 그림을 통해 빈틈없이 연속적으로 '밀집'해서 이루어져 있음을 알 수 있다.
따라서 요소(메모리 주소)까지 아래와 같이 간단히 접근할 수 있다.
검색 대상 요소의 메모리 주소 = 배열의 시작 메모리 주소 + 인덱스 * 요소의 바이트 수
📍인덱스가 0인 요소의 메모리 주소: 1000 + 0 * 8 = 1000
📍인덱스가 1인 요소의 메모리 주소: 1000 + 1 * 8 = 1008
📍인덱스가 2인 요소의 메모리 주소: 1000 + 2 * 8 = 1016
단점
- 정렬이 되지 않은 배열에서 특정 요소를 검색한다면, 배열의 모든 요소를 처음부터 특정 요소를 발견할 때까지 차례대로 검색(선형 검색, 시간복잡도 O(n))해야 한다.
- 배열에 요소의 삽입, 삭제가 이루어질 경우 요소를 연속적으로 유지하기 위해 요소를 이동시켜야 한다.
2) 희소 배열
장점
- 배열의 요소를 위한 각각의 메모리 공간은 동일한 크기를 갖지 않아도 된다.
- 연속적으로 이어져 있지 않을 수도 있다.
- 특정 요소를 검색하거나 요소를 삽입/삭제하는 경우 일반 배열보다 빠르다.
자바스크립트의 배열은 일반적인 배열의 동작을 흉내 낸 특수한 객체다.
위와 같이 console.log 결과를 통해 아래 내용들을 확인할 수 있다.
1. 자바스크립트 배열은 인덱스를 나타내는 문자열 프로퍼티 키를 가진다.
2. length 프로퍼티를 갖는 특수한 객체다.
3. 사실 배열의 요소가 프로퍼티 값이다.
즉, 자바스크립트에서 사용 가능한 모든 값은 객체의 프로퍼티 값이 될 수 있고, 어떤 값이든 배열의 요소가 될 수 있음
단점
- 인덱스로 배열의 요소에 접근하는 경우 일반 배열보다 느리다.
하지만, 역시 똑똑한 개발자들이 자바스크립트에서의 구조적 단점을 보완하기 위해 일반 객체와 구별시켜두었다.
때문에 아래 스크린샷과 같이 Array일 경우 Object 보다 약 2배 정도 빠른 것을 알 수 있다.
* 크롬에서 먼저 찍어보고 vsCode에서도 확인해 봤는데 크롬이 더 빨랐다.
References
https://blog.dashlane.com/how-is-data-stored-in-v8-js-engine-memory/
https://devkly.com/nodejs/javascript-array/
책의 내용중 일부는 아래 사이트를 통해서도 참고 가능하다.
https://poiemaweb.com/js-array-is-not-arrray
'Programming Language > JavaScript' 카테고리의 다른 글
코어 자바스크립트 | 자바스크립트 기본 1 (0) 2022.04.14 코어 자바스크립트 | 소개 (0) 2022.04.14 [JavaScript] charAt(), charCodeAt(), String.fromCharCode() (0) 2022.02.01 [JavaScript] forEach, map, filter, reduce (0) 2022.01.31 [JavaScript] 생활코딩 - 실습1 (0) 2021.06.28