“자바스크립트는 이상하게 동작하기로 유명한 언어입니다.”
아이템 16. number 인덱스 시그니처보다는 Array, 튜플, ArrayLike를 사용하기 #
자바스크립트에서 객체란 키/값 쌍의 모음입니다.
- 키 : 보통 문자열 (ES2015 이후로는 ‘심벌’도 가능)
- ‘숫자’ 불가 : ‘숫자’를 키로 사용할 경우 런타임에 ‘문자열’로 변환됩니다.
- 값 : 어떤 것이든 가능
파이썬이나 자바에서 볼 수 있는 ‘해시 가능(hashable)’ 객체라는 표현이 자바스크립트에서는 없습니다.
만약 더 복잡한 객체(심볼)을 ‘키’로 사용하려고 하면, toString 메서드가 호출되어 객체가 문자열로 변환됩니다.
배열 #
배열은 객체이다.
→(그럼에도) 배열에 숫자 인덱스를 사용하는 것은 당연 시 되어왔다.
→이것들도 런타임 시에 ‘문자열’로 변환된다.
배열의 키를 출력하면 키가 문자열로 출력되는 것을 확인할 수 있다.
x = [1, 2, 3]
Object.keys(x) // ['0', '1', '2']
타입스크립트에서는? #
타입스크립트에서는 이러한 혼란을 개선하기 위해 ‘숫자 키’를 허용한다.
‘문자열 키’와 다른 것으로 인식한다.
다만, 런타임 시에는 역시 ‘문자열 키’로 변환되어 사용된다. (결국에 js 로 변환/사용되는 것이니까)
타입스크립트에서 가능하다는 것은 ‘타입 체크 시점에 오류를 잡을 수 있는 것’ 을 의미한다.
이 부분은 오히려 혼란을 야기시킬 수도 있긴하다.
다만, 책에서는 일반적으로 string 대신 number 를 타입의 인덱스로 사용할 이유는 많지 않다고 한다.
+ for-loop 관련하여… #
for-in
const keys = Object.kins(xs);
for (const key in xs) {
key; // string
const x = xs[key]; // number
// (책에서) for-in 에서는 string->number 로의 변환에 대해서 예외적으로(?) 허용한다고 생각하면 된다고 한다.
}
인덱스를 신경 쓰지 않는다면 : for-of
for (const x of xs) {
x;
}
인덱스의 타입이 중요하다면 : forEach
xs.forEach((x, i) -> {
i;
x;
})
loop 중간에 멈춰야 한다면 : for(;;)
for (let i = 0; i < xs.length; i++) {
const x = xs[i];
if (x<0>) break;
}
타입이 불확실하다면, (대부분의 브라우저, 자바스크립트 엔진에서)
for-in
루프는 (for-of
,for(;;)
)에 비해 몇 배나 느리다.
숫자 인덱스 대신 Array, 튜플, ArrayLike #
이 부분은 실제 사용 후 다시 공감해볼 것
요약 & 정리 #
- 키 : 문자열
- 타입스크립트에서 사용하는 ‘키가 number 인 것’은 순수 타입스크립트에서(타입 체크)만 동작하는 코드
- 숫자 인덱스 대신 Array, 튜플, ArrayLike