강제 형 변환(type coercion)이란?
자바스크립트(JavaScript)에서 강제 형 변환은 타입이 다른 타입으로 변환되는 것을 의미합니다.
명시적 변환은 Number(), String(), Boolean()
을 사용하여 타입을 강제로 변환하는 경우입니다. 명시적 변환은 개발자가 의도하여 타입을 변환하므로 코드를 쉽게 이해할 수 있습니다.
암시적 변환은 특정 연산자 또는 표현식이 사용될 때 동작합니다. 항등 연산자인 ==
는 암시적으로 형 변환하는 연산자로 유명합니다.
1 == '1' // true
1 === '1' // false
1 == '1'
은 서로 다른 타입이지만 암시적으로 형 변환 후 값을 비교하여 True가 반환됩니다.
이번 포스팅은 암시적 변환에 초점을 두어 강제 형 변환을 설명합니다.
JavaScript의 원시 타입 형 변환
JavaScript의 원시 타입으로는 string, number, boolean, null, undefined 등.. 총 8개의 타입이 존재합니다. 원시 타입은 강제 형 변환으로 number 타입을 string 타입으로 변환되거나 string 타입이 boolean 타입으로 변환되는 다양한 케이스가 존재합니다.
▶ 원시 타입을 boolean 타입으로 강제 형 변환
원시 타입은 논리 연산자(&&, ||, !
)를 사용하여 타입을 boolean 타입으로 변환합니다.
if(100 && 'hello') {
// 100 && 'hello' 결과는 true로 평가됩니다.
// 숫자를 불리언으로 변환하면 'true'로 평가되며, 문자열을 불리언으로 변환하면 'true'로 평가됩니다.
}
▶ 원시 타입을 string 타입으로 강제 형 변환
string 타입은 +
연산자를 사용하여 문자열을 결합할 수 있는데, 피연산자 중 문자열이 하나라도 존재하면 문자열로 강제 변환합니다.
true + 'hi'
// 'truehi'
1 + 'hi'
// '1hi'
null + 'hi'
// 'nullhi'
undefined + 'hi'
// 'undefinedhi'
undefined + null
// NaN
undefined + null + 'hi'
// 'NaNhi'
▶ 원시 타입을 number 타입으로 강제 형 변환
다음은 피연산자 중 문자열이 없는 경우입니다. boolean과 number 타입의 값에 +
연산자를 사용하는 예제입니다.
true + true
// 2
// true는 숫자로 변환하면 1, false는 0으로 평가됩니다.
true + false
// 1
true + 10
// 11
다음은 비교 연산자(>, >=, <, <=
)를 사용하여 number 타입과 number 타입이 아닌 값을 비교하는 예제입니다.
true > 10
// false
// true는 숫자로 변환하면 1이며, 10보다 작으므로 비교 결과는 false입니다.
'true' > 10
// false
// 'true'는 불리언 true로 변환되고 불리언 true는 1이므로 비교 결과는 false입니다.
'20' > 10
// true
// '20'은 숫자로 변환되며, 10보다 크기 때문에 비교 결과는 true입니다.
JavaScript의 객체 형 변환
객체 형 변환은 원시 타입보다 좀 더 까다롭습니다.
▶ 논리 연산자에서 사용
객체를 논리 연산자에 사용하는 경우 빈 배열 또는 빈 객체라도 true로 강제 변환됩니다. 객체는 항상 true로 취급합니다.
if([] && true) {
// [] && true 결과는 true로 평가됩니다.
}
if({} && true) {
// {} && true 결과는 true로 평가됩니다.
}
▶ 객체를 숫자 및 문자열로 강제 형 변환
객체를 숫자 및 문자열로 형 변환한다는 것은 비 원시 타입(non-primitive)을 원시 타입(primitive)으로 변환하는 것과 동일한 의미입니다.
모든 객체 프로토타입에는 강제 형 변환에 영향을 미치는 두 가지 함수가 존재합니다. 바로 valueOf()
함수와 toString()
함수입니다.
typeof Object.prototype.valueOf; // "function"
typeof Object.prototype.toString; // "function"
let myObj = {};
myObj.valueOf(); // {}
myObj.toString(); // "[object Object]"
객체를 숫자나 문자열로 형 변환하기 위해 자바스크립트 엔진은 먼저 다음 과정을 수행합니다.
toString()
를 호출할지valueOf()
를 호출할지는 객체의 내부 함수인 DefaultValue()에서 결정합니다.DefaultValue()
함수에 전달된 "힌트"를 기반으로 결정됩니다. 대부분의 경우valueOf()
가 먼저 호출됩니다.- 다음은 (1)에서 반환된 값이 원시 값인지 확인합니다. 원시 값이면 값을 반환하고 그렇지 않으면 (3) 과정을 진행합니다.
- 대체 함수를 호출합니다. 만약, (1)에서
valueOf()
가 호출되었다면 대체 함수는toString()
입니다. 반대로toString()
가 호출되었다면 대체 함수는valueOf()
입니다. - 대체 함수의 반환 값이 원시 값이면인지 확인합니다. 원시 값이면 값을 반환하고 그렇지 않으면
Uncaught TypeError: Cannot convert object to primitive value.
오류가 발생합니다.
다음은 객체 강제 형 변환 몇 가지 예제입니다.
let myObj = {};
myObj.valueOf(); // {}
myObj.toString(); // "[object Object]"
2 + myObj; // '2[object Object]'
대부분의 경우 valueOf()
가 먼저 호출되지만 valueOf()
의 반환 값이 원시 값이 아니므로 대체 함수인 toString()
을 호출합니다.
let myObj = {};
myObj.valueOf = () => "myObj";
myObj.valueOf(); // "myObj"
myObj.toString(); // "[object Object]"
2 + myObj; // "2myObj"
valueOf()
가 기본 값을 반환하도록 객체를 수정하였습니다. valueOf()
가 호출되었고 원시 값을 반환하므로 valueOf()
의 반환 값이 적용되었습니다.
'JavaScript > Tip' 카테고리의 다른 글
[JavaScript]변수가 정의되었는지 확인하는 방법 (0) | 2022.07.03 |
---|---|
[JavaScript]NaN 체크 방법 (0) | 2022.03.27 |
[JavaScript]언더바 변수 (1) | 2022.03.20 |
[JavaScript]if문 간결화 (0) | 2022.01.07 |
[JavaScript]다양한 반복문(for, forEach, for of, for in) (0) | 2021.12.08 |
댓글