-
[JavaScript] 타입 강제변환 - 추상 연산WIL 2024. 1. 14. 01:53
타입 강제변환은 말 그대로 어떤 값의 타입을 변환시키는 것이다.
변환을 시킬때 두 가지로 분리하여 말을 할 수 있는데,
바로 암시적 강제변환(강제변환), 명시적 강제변환(타입 캐스팅)으로 분리하여 말 할 수 있다.
암시적, 명시적 강제변환의 차이
본 글에서 말 하는 명시적, 암시적은 아래와 같다.
명시적 강제변환 : 코드만 봐도 의도적으로 타입 변환을 일으킨다는 사실이 명백한 타입 변환
암시적 강제변환 : 다른 작업 도중 불분명한 부수 효과로 부터 발생하는 타입 변환
코드를 보며 확인해 보자.
const a = 42 const b = a + "" // "42" 암시적 강제변환 const c = String(a) // "42" 명시적 강제변환
위 코드에서 변수 b, c 모두 결과는 string 타입에 42가 출력된다.
그렇다면 왜 변수 b가 암시적 강제변환이라 볼 수 있을까?
이유는 공백 문자열 (" ")과의 + 연산은 문자열 접합(두 문자열을 하나로 합치는) 처리를 의미 하므로
(숨겨진) 부수 효과로 숫자 42를 이와 동등한 문자열 "42"로 강제 변환 한다.
이와 대조적으로 String() 함수는 값을 인자로 받아 명백히 문자열 타입으로 강제변환 한다.
하지만 이것은 String() 이 어떻게 동작을 하는지에 모른다면 String() 에서도 어떤 부수 효과가 있을지 걱정 할 수 있다.
그렇다면 우리는 암시적, 명시적 강제변환을 알아보기전에 어떻게 값이 문자열, 숫자, 불리언 등의 타입이 되는지 알아보자.
추상 연산
ES5 명세를 보면 변환 규칙의 '추상 연산'이 정의되어 있다.
이 중 ToString, ToNumber, ToBoolean에 대해 알아보자.
ToString
문자열이 아닌 값을 문자열 변환 하는 작업은 ToString 추상 연산 로직이 담당한다.
내장 원시 값은 본연의 문자열화 방법이 정해져 있다.
일반 객체는 특별히 지정하지 않으면 기본적으로 toString() 메서드가 내부 [[Class]]를 반환 한다.
const a = {a:1,b:2,c:3} a.toString() //'[object Object]'
배열은 기본적으로 재정의된 toString()이 있다.
문자열 변환시 모든 원소 값이 각각 문자열로 바뀌어 콤마로 분리가 된다.
const a = [1,2,3] a.toString() // 1,2,3
toString() 메서드는 명시적으로도 호출 가능하며,
문자열 콘텍스트에서 문자열이 아닌 값이 있을 경우에도 자동으로 호출된다.
const myArray = [1, 2, 3, "four", { key: "value" }]; // 문자열과 배열을 연결할때 toString() 메서드가 자동으로 호출됨 console.log("My array: " + myArray); // 'My array: 1,2,3,four,[object Object]'
ToNumber
숫자 아닌값을 수식 연산이 가능한 숫자로 변환하는 로직은 toNumber 추상 연산이 담당한다.
예를 들면 true = 1, false = 0, null = 0, undefined = NaN으로 바뀐다.
문자열에 toNumber를 적용시 대부분 숫자로 변환이 되지만 실패하는 경우는 NaN으로 변환이 된다.
(0이 앞에 붙은 8진수는 toNumber에서 10진수로 처리한다.)
객체, 배열 같은 경우는 우선 동등한 원시 값으로 변환 후 아직 숫자가 아닌 원시 값을 숫자로 강제 변환한다.
동등한 원시 값으로 바꾸기 위해 toPrimitive 추상 연산을 사용하고,
해당 연산 과정에서 객체가 valueOf() 메스드를 확인 후 사용할 수 없을 경우 toString을 이용해 강제 변환한다.
만약, 원시 값으로 바꿀 수 없을 땐 TypeError 오류를 던진다.
const a = [4, 2]; a.toString = function() { return this.join(""); }; ƒ () { return this.join(""); } Number(a); // 42 Number([4,2]); // NaN Number([]); // 0 Number(""); // 0 Number(null); // 0 Number(false); // 0 Number(true); // 1
ToBoolean
흔히들 1 = true 0 = false로 생각하지만, 자바스크립트에서는 숫자는 숫자이고 불리언은 불리언으로 서로 별개이다.
1을 true로 0을 false로 강제 변환이 가능하지만 두 값이 똑같은건 아니다.
console.log(1 === true) // false console.log(0 === false) // false // 위 코드에서 2개가 왜 false로 결과가 나오는지는 추후 동등 비교에서 알아보자.
자바스크립트에서는 불리언으로 강제 변환시 false가 되는 몇 안되는 특별한 값들이 있다.
인자 타입 결과값 Undefuned false Null false Boolean 인자 값과 동일(변환 안 함) Number 인자가 +0. -0, NaN이면 false 그 외 true String 인자가 공백 문자열(length가 0)이면 false, 그 외에는 true Object(array, function) true 위 표에 나오는 값들이 fasly한 값이며 해당 값 이외에 값들은 전부 true로 변환한다.
다음에는 강제적, 암시적 강제변환과 동등 비교등 연산자에 대해 정리해보자.
[참고] You Don't Know JS
'WIL' 카테고리의 다른 글
자바스크립트 이벤트 루프(Event Loop) (1) 2024.03.24 Socket-io, Tanstack-Query 사용해 커스텀 훅 만들기 (0) 2024.03.04 [JavaScript] 자바스크립트 값, 레퍼런스 (0) 2023.07.27 [JavaScript] 자바스크립트 버블링 이벤트 막기 (1) 2023.07.23 [JavaScript] 자바스크립트 타입에 대해서 알아보자 (1) 2023.07.11