2019. 11. 28. 12:33ㆍProgramming/JavaScript
[Javascript] 배열 초기화 시 new Array()보다는 []를 사용하자
The Javascript Handbook
을 읽던 도중new Array()
를 사용하여 배열을 초기화하는 것은 권장하지 않는다는 내용을 발견했는데, 그 이유에 대해서는 따로 기술하지 않고 있었다. 다른 분들께 질문을 해보니 직관성 및 일관성과 관련된 내용과, ECMA문서의22.1.1.2 Array(len)
항목의 내용을 볼 수 있었다. 아래는 해당 내용을 정리한 내용이다. (사실 서문에 모든 내용이 다 들어가있다' ㅅ';)
The Javascript Handbook
의 Arrays챕터에 기재되어있는 Initialize array항목을 보면, typed array를 초기화하는 게 아닐때는 new Array()
로 배열을 초기화하지 말라는 내용이 있다. 하지만 그 이유에 대해서는 따로 기재된 내용이 없다.
const a = new Array() //never use
const a = new Array(1, 2, 3) //never use
[]
대신 new Array()
를 사용해도 초기화는 될텐데, 왜 사용하지 말라고 하는걸까? 심지어 주석에는 //never use
라고 적혀있을 정도다. 궁금해서 다른 분들에게 물어보고, 답변과 함께 ECMAScript 문서의 내용을 정리해봤다.
ECAMScript 문서 22.1.1.1 Array()
항목을 확인해보자. new Array()
에 전달하는 인자값이 아무것도 없는 경우, 다음과 같이 길이가 0인 Array 객체를 반환하게 된다.
22.1.1.1 Array ( )
This description applies if and only if the Array constructor is called with no arguments.
- Let numberOfArgs be the number of arguments passed to this function call.
- Assert: numberOfArgs = 0.
- If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
- Let proto be ? GetPrototypeFromConstructor(newTarget, "%Array.prototype%").
- Return ! ArrayCreate(0, proto).
일단 여기서 new Array()
를 호출했을 때 결과 자체는 []
을 사용했을때와 동일하다는 것을 알 수 있다. 다만 코드의 길이는 new Array()
를 호출했을 때보다 []
를 사용하는 게 더 짧아지게 된다. 글자수뿐만 아니라 빈 배열을 생성한다는 점에서, []
를 사용하는 쪽이 좀 더 직관적이기도 하다. 하지만 여기까지만 봐서는 new Array()
를 사용하지 말라는 내용이 잘 이해되지 않는다. 이제 new Array()
에 인자값을 1개 전달하는 경우, []
를 호출하는 것과 어떤 차이점을 보이는지 살펴보도록 하자.
22.1.1.2 Array ( len )
This description applies if and only if the Array constructor is called with exactly one argument.
- Let numberOfArgs be the number of arguments passed to this function call.
- Assert: numberOfArgs = 1.
- If NewTarget is undefined, let newTarget be the active function object; else let newTarget be NewTarget.
- Let proto be ? GetPrototypeFromConstructor(newTarget, "%Array.prototype%").
- Let array be ! ArrayCreate(0, proto).
- If Type(len) is not Number, then
a. Perform ! CreateDataPropertyOrThrow(array, "0", len).
b. Let intLen be 1. - Else,
a. Let intLen be ToUint32(len).
b. If intLen ≠ len, throw a RangeError exception. - Perform ! Set(array, "length", intLen, true).*
- Return array.
인자를 1개 전달했을때는 new Array()
를 이용하여 배열을 초기와했을때와, []
를 이용하여 배열을 초기화했을때의 차이가 명백해진다. 값이 Number
인지 아닌지에 따라서 달라지는데, Number
가 아닐 경우에는 배열의 첫 번째 요소로 할당이 된다. 하지만 값이 Number
일 경우에는 인자로 넘겨진 값과 같은 크기의 빈 배열이 생성된다.
const a = new Array("3") // ["3"]
const b = new Array(3) // [empty x 3]
const c = ["3"] // ["3"]
const d = [3] // [3]
위에서 보이듯이 new Array()
를 사용하여 배열을 초기화 했을때는, []
를 사용해서 배열을 초기화했을때와 다르게 동작한다. 일관성이 부족하다는 느낌도 없잖아있다.
7-b
를 보면 len
값을 ToUInt32
를 사용하여 정수형으로 변환한다. 그리고 len
값과 ToUInt32(len)
의 결과값이 같지 않으면, RangeError exception
을 발생시킨다는 걸 알 수 있다. 한번 소수를 넘겨보자.
const e = new Array(1.2) // Uncaught RangeError: Invalid array length
const f = [1.2] // [1.2]
new Array(1.2)
를 호출하면 인자로 전달한 1.2
를 정수로 변경하면, 당연히 1.2
는 아니지 않겠는가. 결국 7-b
에 의해서 RangeError exception
을 뱉어버린다. 반면 []
를 통해서 초기화한 경우에는, RangeError exception
이 발생할 일이 없다.
22.1.1.3 Array(...items)
의 내용은 22.1.1.1 Array()
과 마찬가지로, []
을 이용할때와 결과적인 차이를 보이지 않는다. 즉, new Array()
를 사용하여 배열을 초기화하지 않는 이유는 22.1.1.2 Array(len)
에서 len
값이 Number
로 주어지는지 아닌지, 그리고 len
값이 정수인지 아닌지에 따라서 동작이 다르기 때문인 듯 하다. 직관성, 그리고 일관성의 문제라고 해야하나.
앞으로는 배열을 초기화할 때, new Array()
대신 []
를 사용해야겠다. ' ㅅ')
'Programming > JavaScript' 카테고리의 다른 글
노션으로 관리하고 있는 Javascript 위클리 뉴스레터 정리 페이지 (0) | 2022.03.23 |
---|---|
[JavaScript] Object Literal Property Value Shorthand (0) | 2021.12.08 |
자바스크립트로 알아보는 함수형 프로그래밍 정리노트#4, 함수형으로 전환하기 (0) | 2019.09.22 |
자바스크립트로 알아보는 함수형 프로그래밍 정리노트 #3 (0) | 2019.09.15 |
자바스크립트로 알아보는 함수형 프로그래밍 정리노트 #2 (0) | 2019.09.15 |