티스토리 뷰

Java Script & HTML

자바스크립트 배열

LichKing 2017. 10. 3. 12:13

요즘 You don't know JS 라는 책을 보고있는데 배열 생성 방식에 대한 부분에 지면을 꽤나 할애하고있어 해당 부분에 대한 정리와 내 생각을 포스팅하고자한다.


1. 배열생성

자바스크립트에서 배열을 생성하는 방식은 2가지가 있다. 여타 객체를 생성하듯 생성자를 사용할 수도 있고 언어차원에서 제공하는 리터럴 방식을 사용할 수도 있다. 보통은 타이핑 양도 적고, 가독성에서도 우월하고 성능에서까지 좋은 리터럴 방식을 권장하고, 사용한다. 개인적으로 리터럴 표현이 아닌 생성자를 사용해야할 경우는 아무리 생각해도 떠오르지않는다.


var arr1 = [];
var arr2 = new Array();


IDE 마저도 리터럴로 바꾸라고 한다.


2. 배열 생성자

이미 리터럴의 우수함때문에 생성자를 사용할 이유가 없지만 생성자는 이외에도 사용하지말아야할 이유가 있다. 이는 배열 생성자의 결함인데 인자 개수에 따라 다르게 작동하기 때문이다.


var arr1 = new Array(5);
var arr2 = new Array(5, 6, 7);

console.log(arr1.length);
console.log(arr2.length);


결과를 확인해보면 알겠지만 인자가 1개일때는 배열의 크기로 사용하고 인자가 여러개일땐 배열의 요소로 사용하기때문에 두 결과의 일관성이 없다. 한가지 더 큰 문제는 인자가 1개지만 타입이 숫자가 아닌경우다.


var arr1 = new Array("5");


이경우에는 또 배열의 초기 크기가 아니라 배열의 요소로 사용한다. 이런 문제들을 방지하기위해선 일단 자바스크립트 스펙에 대해 상세히 알아야하지만 상세히 알고있다고 하더라도 잠깐 깜빡하는 순간 프로그램을 의도대로 작동하지 않을 것이다.


더군다나 자바스크립트의 배열은 C나 Java의 배열처럼 크기가 고정되어있는게 아니라 얼마든지 가변적으로 크기를 변경할 수 있기때문에 초기화시점에 배열의 크기를 정하는게 큰 의미도 없다.


3. 빈 배열 생성

이번 포스팅을 작성하게된 계기이기도 한데 You Don't know JS 는 빈 배열 생성에 대해 꽤 많은 지면을 할애하고있다. 자바스크립트 배열의 문제라고 꼬집은 저자는 생성하는 방식에 따라 빈배열의 출력 내용이 다름에 매우 분노한다.


var arr1 = [];
arr1.length = 3;

var arr2 = [undefined, undefined, undefined];

var arr3 = new Array(3);

var arr4 = new Array(undefined, undefined, undefined);

console.log(arr1);
console.log(arr2);
console.log(arr3);
console.log(arr4);


해당 내용 출력은 브라우저마다 다른데, 국내에서 가장 많이 사용되는 브라우저인 크롬과 IE의 결과를 비교해보자.


크롬


IE


두 브라우저의 출력이 다르다! 현재 포스팅하는 PC에 파이어폭스는 설치되어있지않아 확인하지 못했지만 저자는 파이어폭스에 대해서도 논한다. 참고로 크롬과 같은 크로니움 엔진을 사용한 웨일 브라우저는 크롬과 결과가 같다. 모든 배열에 대해 동일한 결과를 보여주는 IE는 오히려 신경쓸게 없을거같은데 크롬은 왜 결과가 다를까? 아마도 명시적으로 undefined 초기화를 해준 요소와 명시적인 초기화가 없는 요소(undeclared)를 내부적으로 다르게 표현하는것 같다. 


var arr1 = [];
arr1.length = 3;
arr1[1] = undefined;

console.log(arr1);


이렇게 테스트를 해보면 명확하게 이해가 될것이다. 여튼 저자는 이 다른 출력을 가지고 피토하며 결국 내놓은 최후의 해법은 빈배열은 이렇게 초기화하자는 것이다.


var arr1 = Array.apply(null, {length:3});
console.log(arr1);


이 내용에 대해 한글 번역판 책은 약 5페이지를 할애하고있다. 다만 개인적으로 이 책을 보면서 느낀부분이 이부분에 5페이지나 할애할 필요가있나? 하는 것이다. 개발하면서 브라우저의 출력 결과를 활용할 일은 거의 없다. 더군다나 배열이나 객체와 같은 참조 변수를 그냥 쌩으로 출력하는 경우는 더더욱이 없다. 참고로 이 연산은 브라우저 상관없이 true를 반환한다.


var arr = [];
arr.length = 3;

arr[0] === undefined;


즉 크롬에서 undefined로 초기화되지않은 요소의 '브라우저 출력' 결과를 좀 다르게 출력할뿐 실제 개발에서 사용될 비교문에서는 전혀 문제가 발생하지않는다. 이게 이렇게 열을 낼만한 일인가? 싶은게 솔직한 내 심정이다.


4. 정리

자바스크립트는 배열의 리터럴을 제공한다. 또한 이번 포스팅에선 언급하지않았는데 객체의 리터럴도 제공한다. 기본적으로 대다수의 언어에서 리터럴을 제공하는 표현에 대해서는 성능과 가독성 면에서 우수하다. 특히나 자바스크립트의 배열 생성자는 인자의 타입과 개수에 따라 다르게 작동되도록 구현되어있으니 괜한 문제를 일으키고싶은게 아니라면 애초에 싹을 없애버리도록 리터럴을 사용하는게 좋다.


빈 요소들(undefined)로 배열의 초기 크기를 지정하는 경우 지정 방법에 따라 브라우저별로 출력되는 방식이 좀 다른 문제가 있으나 출력에서만 다를뿐 내부 연산에서는 차이가 없다. 또한 동적으로 크기가 바뀌는 자바스크립트 배열의 초기크기를 지정하는게 큰 의미가 없고, 더욱이 그걸 그대로 브라우저 콘솔창에 출력하는 경우는 거의 없으니 이것 때문에 무언가 코드를 변경하는건 무의미하다고 생각한다.


#참고

YOU DON'T KNOW JS

Effective JavaScript Item 52. 생성자 대신 배열 리터럴을 사용하라

'Java Script & HTML' 카테고리의 다른 글

자바스크립트 배열  (0) 2017.10.03
자바스크립트 객체 JSON화 하기  (1) 2017.09.23
karma mocha 테스트 환경 구축  (0) 2017.09.16
JavaScript에서 정규 표현식 활용하기  (0) 2017.05.27
ES5 주요 함수 분석  (0) 2017.05.17
ES5 Array method  (0) 2017.05.13
댓글
댓글쓰기 폼