Notice
Recent Posts
Recent Comments
Link
«   2025/05   »
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
Tags
more
Archives
Today
Total
관리 메뉴

민규의 개발블로그

자바스크립트 강제변환-1 본문

Javascript

자바스크립트 강제변환-1

규몽 2020. 11. 16. 17:00

 


값 변환

 

어떤 값을 다른 타입의 값으로 바꾸는 과정이 명시적이면 '타입 캐스팅', 암시적이면 강제변환이라고 한다.

 

자바스크립트에서는 명시적 강제변환과 암시적 강제변환이 있다.

 

이 둘의 차이는 '명시적 강제변환'은 코드만 봐도 의도적으로 타입변환을 일으킨다는 사실이 명백함, '암시적 강제변환'은 다른 작업 도중 불분명한 부수 효과로부터 발생하는 타입변환이다.

 

내가 작성한 코드를 협업할 때 같은 팀 개발자가 보고 어떻게 받아들일지 신경써야 하기 때문에 배운다 생각한다.

 

 

추상 연산

 

ToString

 

문자열이 아닌 값 -> 문자열 변환 작업은 ToString 추상 연산 로직이 담당한다.

내장 원시 값은 본연의 문자열화 방법이 정해져 있다. 

ex) null > "null", undefined> "undefined", true > "true"

숫자는 그냥 문자열로 바뀌고 너무 작거나 큰 값은 지수 형태로 바뀐다.

 

객체는 특별히 지정하지 않으면 기본적으로 toString( ) 메서드가 내부 [[Class]]를 반환한다.

배열은 기본적으로 재정의된 toString( )이 있는데 문자열 변환 시 모든 원소 값이 콤마로 분리된 형태로 이어진다. 

 

 

 

JSON 문자열화

 

대부분 단순 값들은 직렬화 결과가 반드시 문자열이라는 점을 제외하고는, JSON 문자열화나 toString( ) 변환이나 기본적으로 같은 로직이다.

 

 

 

JSON 안전 값(JSON 표현형으로 확실히 나타낼 수 있는 값)은 모두 JSON.stringify( )로 문자열화 할 수 있는데

안전 값이 아닌 (undefined, 함수, 심벌, 환형 참조 객체)는 안된다.

 

JSON.stringify( )는 인자가 undefined, 함수, 심벌 값이면 자동으로 누락시키며 이런 값들이 만약 배열에 포함되어 있으면 null로 바꾼다. 객체 프로퍼티에 있으면 지워버린다.

 

 

 

JSON.stringify( ) 에 환형 참조 객체를 넘기면 에러가 난다.

객체 자체에 toJSON( ) 메서드가 정의되어 있다면, 먼저 이 메서드를 호출하여 직렬화한 값을 반환한다.

부적절한 JSON 값이나 직렬화하기 곤란한 객체 값을 문자열화 하려면 toJSON( ) 메서드를 따로 정의해야한다.

 

toJSON( )이 JSON 문자열 표현형을 반환하리라 넘겨짚는 건 오해다.

toJSON( )의 역활은 '문자열화하기 적당한 JSON 안전 값으로 바꾸는 것'이지, 'JSON 문자열로 바꾸는 것'이 아니다.

 

 

 

JSON.stringify( ) 두 번째 선택 인자로 배열 아니면 함수 형태의 대체자를 넣으면 객체를 재귀적으로 직렬화하면서 필터링 하는 방법이 있다.

 

대체자가 배열이면 전체 원소는 문자열이여야 하고 각 원소는 객체 직렬화의 대상 프로퍼티명이다. 즉, 여기에 포함되지 않은 프로퍼티는 직렬화 과정에서 빠진다.

 

대체자가 함수면 처음 한 번은 객체 자신에 대해, 그 다음엔 각 객체 프로퍼티별로 한 번씩 실행하면서 매번 키와 두 인자를 전달한다. 직렬화 과정에서 해당 키를 건너뛰려면 undefined를, 그 외엔 해당 값을 반환한다.

 

 

 

JSON.stringify( )은 직접적인 강제변환의 형식은 아니지만 두 가지 이유로 ToString 강제변환과 연관된다.

  • 문자열, 숫자, 불리언, null 값이 JSON으로 문자열화하는 방식은 ToString 추상 연산의 규칙에 따라 문자열 값으로 강제변환되는 방식과 동일하다.
  • JSON.stringify( )에 전달한 객체가 자체 toJSON( ) 메서드를 갖고 있다면, 문자열화 전 toJSON( )가 자동 호출되어 JSON 안전 값으로 '강제변환'된다.

ToNumber

'숫자 아닌 값 -> 수식 연산이 가능한 숫자' 변환 로직이다.

 

true는 1, false는 0이 된다. undefined는 NaN으로, null은 0으로 바뀐다.

문자열 값에 ToNumber를 적용하면 대부분 숫자 리터럴 규칙/구문과 비슷하게 작동한다. 변환이 실패하면 결과는 NaN이다. 0이 앞에 붙은 8진수는 ToNumber에서 올바른 숫자 리터럴이라도 8진수로 처리하지 않는다.(10진수로 처리)

 

객체(배열)는 동등한 원시 값으로 변환 후 그 결괏값을 ToNumber 규칙에 의해 강제변환한다.

동등한 원시 값으로 바꾸기 위해 추상 연산 과정에서 해당 객체가 valueOf( ) 메서드를 구현했는지 확인한다.

valueOf( )를 쓸 수 있고 반환 값이 원시 값이면 그대로 강제변환하되, 그렇지 않을 경우 toString( )을 이용하여 강제변환한다. 둘다 안될 경우 TypeError 오류를 던진다.

 

ToBoolean

 

Falsy 값

 

true/false가 아닌 값을 불리언에 상당한 값으로 강제변환 했을 때 자바스크립트에서 모든 값은 둘 중 하나다.

  • 불리언으로 강제변환하면 false가 되는 값
  • 위를 제외한 모든 값

 

불리언으로 강제변환 시 false가 되는 값은 몇 개 없다.

 

  • undefined
  • null
  • false
  • +0, -0, NaN
  • ""

 

명시적 강제변환

 

명시적 강제변환은 분명하고 확실한 타입변환이다. 명확하면 명확할수록 다른 개발자가 내 코드를 보더라도 쓸데없이 내 의도를 추론할 필요없이 단번에 이해 할수 있게 하자!

 

 

문자열 <-> 숫자

 

문자열,숫자 강제변환은 String( )과 Number( ) 함수를 이용하는데, 앞에 new 키워드가 붙지 않기 때문에 객체 래퍼를 생성하는 것이 아니다. 이것 말고도 이런 것도 있다.

 

 

 

a.toString( )은 겉보기엔 명시적이지만 원시 값 10에는 toString( ) 메서드가 없으므로 10 을 객체 래퍼로 박싱해야 되어 명시적으로 암시적인 작동이다.

 

+c는 단항 연산자다. 피연산자 c를 숫자로, 명시적 강제변환하지만 혼동을 줄 수 있기 때문에 되도록 쓰지말자.

 

 

날짜 -> 숫자

 

현재 타임스탬프는 Date.now( )로, 그 외 특정 날짜/시간의 타임스탬프는 new Date( ).getTime( )를 쓰자

 

틸드( ~ )

 

틸드는 강제변환 연산자이다. 책을 읽으면서 처음 알게 되었는데 유용한 것 같다.

 

자바스크립트 비트 연산자는 32비트 연산만 가능하다. 즉, 비트 연산을 하면 피연산자는 32비트 값으로 강제로 맞춰지는데, ToInt32 추상 연산이 이 역할을 맡는다.

우선 ToInt32은 ToNumber 강제변환한다. "123" 이라면 ToInt32 규칙을 적용하기 전 123으로 바꾼다.

 

엄밀히 말하면 타입이 바뀐 것은 아니므로 강제변환은 아니지만 숫자 값에 | 나 ~ 비트 연산자를 적용하면 전혀 다른 숫자 값을 생성하는 강제변환 효과가 있다.

 

 

이러한 특수 숫자들은 32비트로 나타내는 것이 불가능하므로 연산 결과는 0이다.

 

~연산자는 먼저 32비트 숫자로 강제변환 한 후 NOT 연산을 한다.

~x 는 대략 -(x+1)과 같다. ~10; // -(10+1) ==> -11

 

-(x+1)의 연산 결과를 0으로 만드는 유일한 값은 -1이다.

일정 범위 내의 숫자 값에 ~연산을 할 경우 입력 값이 -1이면 falsy한 0 그 외엔 truthy한 숫자 값이 산출된다.

 

~를 indexOf( )에서 사용시 이런식으로 어떤 값을 강제변환하여 불리언 값으로 적절하게 만들 수 있다.

 

 

 

숫자 형태의 문자열 파싱

 

Number( )와 parseInt( ) 차이

강제 변환은 비 숫자형 문자를 허용하지 않기 때문에 NaN를 내고 멈춘다.

파싱은 비 숫자형 문자를 허용한다.

 

 

명시적 강제변환 - 불리언( !! )

 

Boolean( )은 명시적인 강제변환 방법이지만 자주 쓰이지는 않는다 + 단항 연산자가 값을 숫자로 강제변환하는 것처럼 ! 부정 단항 연산자도 값을 불리언으로 명시적으로 강제변환한다. 문제는 그 과정에서 truthy, falsy까지 뒤바뀐다. 그래서

일반적으로 자바스크립트 개발 시 불리언 값으로 명시적인 강제변환을 할땐 !! 이중부정 연산자를 사용한다. 두번째 !이 패리티를 다시 원상 복구하기 때문이다.

 

 

'Javascript' 카테고리의 다른 글

자바스크립트 문법  (0) 2020.11.19
자바스크립트 강제변환-2  (0) 2020.11.17
자바스크립트 네이티브  (0) 2020.11.13
자바스크립트 값  (0) 2020.11.12
JavaScript 타입  (0) 2020.11.11
Comments