다음 코드 조각은 의외의 결과를 출력합니다. 첫째, 나머지 연산자(% , 모듈로 연산자)가 문자열에 대해서도 정상적으로 동작하는 것을 확인할 수 있습니다. 둘째, 두 문자열의 결합이 예상과 다른 어색한 결과를 만들어냅니다.
그렇다면 자바스크립트는 왜 이런 방식으로 동작하는 걸까요?
문제가 되는 코드는 다음과 같습니다.
예제
const numStr = '127';
const result = numStr % 5;
const firstName = 'Armaan';
const lastName = 'Malik';
const fullName = firstName + + lastName;
console.log('modulo result: ', result);
console.log('full name: ', fullName);출력 결과
modulo result: 2 full name: ArmaanNaN
코드를 분석하기 전에, 먼저 자바스크립트의 가장 근본적인 주제 중 하나인 타입 강제 변환(Type Coercion)에 대해 간단히 알아보겠습니다.
타입 강제 변환이란?
타입 강제 변환이란 자바스크립트 엔진이 한 데이터 타입을 다른 데이터 타입으로 변경하는 메커니즘입니다. 유효한 타입 강제 변환의 예로는 문자열을 불리언으로 바꾸거나, 숫자를 문자열로 바꾸는 것 등이 있습니다.
타입 강제 변환은 매우 방대한 주제이므로, 이 글에서는 위 코드 조각에 사용된 부분만 집중적으로 살펴보겠습니다. 타입 강제 변환에는 두 가지 종류가 있으며, 그중 엔진이 자동으로 수행하는 것을 암묵적 타입 강제 변환(Implicit Type Coercion)이라고 부릅니다.
암묵적 타입 강제 변환은 다음 규칙을 따릅니다.
모든 데이터 타입(원시 타입 및 비원시 타입 포함)은 아래와 같이 암묵적으로 변환됩니다.
문자열(String) — 이항(binary) + 연산자와 함께 사용될 때
숫자(Number) — 산술 연산자(+, -, /, *, % 등)와 함께 사용될 때. 단, 숫자 강제 변환을 트리거하는 것은 단항(unary) + 연산자뿐이며, 비교 연산자·비트 연산자·느슨한 동등 연산자(==)와 함께 쓰이는 이항 + 연산자는 여기에 해당하지 않습니다.
불리언(Boolean) — 논리 연산자(!, &&, ||)와 함께 사용될 때
***또 하나 반드시 기억해야 할 점은, 단항(+) 연산자의 우선순위가 이항(+) 연산자보다 높다는 사실입니다.
코드 상세 분석
개념이 정리되었으니, 이제 코드를 한 줄씩 살펴보겠습니다.
Line 2 → result = '127' % 5;
% 연산자를 만나면 암묵적 타입 강제 변환이 발생하여 문자열 '127'이 숫자 127로 변환됩니다. 따라서 나눗셈의 나머지인 2가 result 변수에 저장됩니다.
Line 5 → fullName = firstName + + lastName;
fullName = firstName + (+lastName);
일반적인 경우 연산은 왼쪽에서 오른쪽으로 진행되지만, 단항 연산자의 우선순위가 더 높기 때문에 lastName이 먼저 숫자로 변환됩니다. 문자열 'Malik'은 숫자로 변환될 수 없으므로 NaN이 되고, 전체 식은 다음과 같이 바뀝니다.
fullName = firstName + NaN;
문자열과 NaN을 이항 + 연산자로 결합하면 문자열 연결이 일어나고, 최종 결과는 다음과 같습니다.
fullName = ArmaanNaN