아이템 16. Number 인덱스 시그니처보다는 Array, 튜플, ArrayLike를 사용하기

아이템 16. Number 인덱스 시그니처보다는 Array, 튜플, ArrayLike를 사용하기

“자바스크립트는 이상하게 동작하기로 유명한 언어입니다.”

아이템 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 #

이 부분은 실제 사용 후 다시 공감해볼 것



요약 & 정리 #

  1. 키 : 문자열
    • 타입스크립트에서 사용하는 ‘키가 number 인 것’은 순수 타입스크립트에서(타입 체크)만 동작하는 코드
  2. 숫자 인덱스 대신 Array, 튜플, ArrayLike