JavaScript/Tip

[JavaScript]강제 형 변환(type coercion)

DevStory 2022. 3. 25.

강제 형 변환(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]"

객체를 숫자나 문자열로 형 변환하기 위해 자바스크립트 엔진은 먼저 다음 과정을 수행합니다.

  1. toString()를 호출할지 valueOf()를 호출할지는 객체의 내부 함수인 DefaultValue()에서 결정합니다. DefaultValue() 함수에 전달된 "힌트"를 기반으로 결정됩니다. 대부분의 경우 valueOf()가 먼저 호출됩니다.
  2. 다음은 (1)에서 반환된 값이 원시 값인지 확인합니다. 원시 값이면 값을 반환하고 그렇지 않으면 (3) 과정을 진행합니다.
  3. 대체 함수를 호출합니다. 만약, (1)에서 valueOf()가 호출되었다면 대체 함수는 toString()입니다. 반대로 toString()가 호출되었다면 대체 함수는 valueOf()입니다.
  4. 대체 함수의 반환 값이 원시 값이면인지 확인합니다. 원시 값이면 값을 반환하고 그렇지 않으면 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()의 반환 값이 적용되었습니다.

반응형

댓글