자바스크립트에서는 직접 형변환 함수를 쓰지 않더라도, 연산을 할 때 자동으로 형변환이 이루어진다. 이 자동 형변환은 자바스크립트가 일정한 규칙에 따라 수행하기 때문에, 다른 자료형끼리도 연산이 가능해진다. 예를 들어, 숫자
, 문자열
, 불리언
등이 섞인 표현식을 연산할 때 자바스크립트가 알아서 각 자료형을 필요한 형태로 바꿔준다.
하지만 자동 형변환 덕분에 코드가 짧고 간단하게 작성될 수 있는 반면, 예상하지 못한 결과가 나올 때도 있다. 자바스크립트는 연산이 가능한 한 코드가 중단되지 않도록 서로 다른 자료형도 맞춰서 처리하려고 하기 때문에, 특히 더하기(+
) 연산자처럼 숫자 덧셈과 문자열 연결을 동시에 수행하는 경우에는 더욱 주의해야 한다.
이번 글에서는 자바스크립트의 산술 연산자, 관계 비교 연산자, 동등 및 일치 연산자가 어떻게 자동 형변환을 처리하는지 깊이 있게 살펴보고, 예상하지 못한 결과가 나올 수 있는 부분을 정리해봤다.
자바스크립트의 산술 연산자에는 +
, -
, *
, /
, %
, **
가 있다. 기본적으로 산술 연산은 연산 전에 두 값을 숫자형으로 변환해서 계산하지만, +
연산자는 예외적으로 문자열이 포함되면 문자열 연결을 우선한다.
⚠️ 주의: + 연산자를 사용할 때는 자동 형변환이 어떻게 이루어지는지 주의 깊게 살펴봐야 한다.
+
연산자+
연산자는 덧셈과 문자열 연결 두 가지 역할을 한다. 피연산자 중 하나라도 문자열이 포함되면 전체를 문자열로 변환해서 연결하기 때문에, 예상치 못한 결과가 발생할 수 있다.
+
연산자와 자동 형변환console.log('4' + 2); // '42' (문자열 연결)
console.log('Hello' + true); // 'Hellotrue' (문자열 연결)
console.log('10' + null); // '10null' (문자열 연결)
console.log('5' + undefined); // '5undefined' (문자열 연결)
위 예제에서 볼 수 있듯이, +
연산자에서 하나라도 문자열이 포함되면 전체가 문자열로 변환되어 문자열 연결이 일어난다. 예를 들어, '4' + 2
는 숫자 2가 문자열로 변환되어 '42'
가 된다.
+
연산자에서 숫자 덧셈을 명확히 하려면, Number()
로 문자열을 명시적으로 숫자형으로 변환한 후 연산하는 것이 좋다.
console.log(Number('4') + 2); // 6 (명시적 숫자 변환)
나머지 산술 연산자(-
, *
, /
, %
, **
)는 연산 전에 두 피연산자를 숫자형으로 변환해서 계산을 진행한다. 문자열과 다른 자료형이 만나더라도 숫자로 변환되어 연산되기 때문에 +
연산자와는 다르게 작동한다.
console.log('4' - 2); // 2 (문자열이 숫자로 변환되어 연산)
console.log('4' * 2); // 8 (문자열이 숫자로 변환되어 연산)
console.log('4' / 2); // 2 (문자열이 숫자로 변환되어 연산)
console.log('10' % 3); // 1 (문자열이 숫자로 변환되어 연산)
console.log(2 ** '3'); // 8 (문자열이 숫자로 변환되어 연산)
console.log('hello' - 1); // NaN (숫자로 변환 불가한 문자열)
console.log(true * 3); // 3 (true가 1로 변환)
console.log(false - 1); // -1 (false가 0으로 변환)
console.log(null + 5); // 5 (null이 0으로 변환)
console.log(undefined + 3); // NaN (undefined는 숫자로 변환 불가)
관계 비교 연산자(>
, <
, >=
, <=
)는 대부분 두 값을 숫자형으로 변환 후 비교한다. 단, 문자열끼리 비교하는 경우는 예외로 알파벳 순서에 따라 비교한다.
console.log('3' > 2); // true ('3'이 숫자 3으로 변환됨)
console.log(true < 2); // true (true가 1로 변환됨)
console.log('2' <= 2); // true ('2'가 숫자 2로 변환됨)
console.log('abc' > 'a'); // true (문자열 비교, 알파벳 순서)
console.log('abc' > 'abd'); // false (알파벳 순서)
console.log('hello' < 'world'); // true (문자열 비교, 알파벳 순서)
⚠️ 주의: NaN이 포함된 모든 비교는 항상 false로 평가된다. 예를 들어, NaN < 5, NaN > 1, NaN == NaN은 모두 false다.
자바스크립트의 동등(==) 연산자와 일치(===) 연산자는 형변환 허용 여부에서 차이가 있다.
==
연산자: 형변환을 허용하며, 형이 다르더라도 값이 같으면 true를 반환한다.===
연산자: 형변환 없이 값과 자료형이 모두 같아야 true를 반환한다.console.log(1 == '1'); // true ('1'이 숫자 1로 변환됨)
console.log(1 === '1'); // false (형변환 없음, 자료형이 다름)
console.log(true == 1); // true (true가 1로 변환됨)
console.log(true === 1); // false (형변환 없음, 자료형이 다름)
console.log(null == undefined); // true (둘 다 '비어 있음'으로 처리됨)
console.log(null === undefined); // false (자료형이 다름)
⚠️ 주의: == 연산자는 자동으로 형변환이 일어나기 때문에 예상치 못한 결과가 발생할 수 있다. 자바스크립트에서는 형변환을 허용하는 == 연산자를 사용할 때 논리적 오류가 발생할 가능성이 높다. 일반적으로 일치 연산자(===)를 사용하는 것이 안전하다.
연산자 | 설명 | 예제 | 주의할 점 |
---|---|---|---|
+ | 숫자 덧셈 또는 문자열 연결 | '4' + 2 ➔ '42' | 피연산자 중 하나라도 문자열이면 전체가 문자열로 변환됨 |
- | 뺄셈 | '4' - true ➔ 3 | 숫자형 변환 후 연산 |
* | 곱셈 | '4' * 2 ➔ 8 | 숫자형 변환 후 연산 |
/ | 나눗셈 | '4' / 2 ➔ 2 | 숫자형 변환 후 연산 |
% | 나머지 연산 | 5 % 2 ➔ 1 | 숫자형 변환 후 연산 |
** | 거듭제곱 | 2 ** 3 ➔ 8 | 숫자형 변환 후 연산 |
== | 형변환 허용 후 비교 | 1 == '1' ➔ true | 예상치 못한 결과를 초래할 수 있음 |
=== | 형변환 없이 자료형과 값이 동일한지 비교 | 1 === '1' ➔ false | 더 안전한 비교 |
- 산술 연산자: 대부분 숫자형으로 변환 후 연산을 진행하지만,
+
연산자는 문자열 연결 기능이 있어 피연산자 중 하나가 문자열이면 전체가 문자열로 변환된다. NaN은 연산에서 항상 NaN을 반환한다.- 관계 비교 연산자: 숫자형으로 변환 후 비교하며, 문자열끼리 비교할 때는 알파벳 순서로 비교된다. NaN을 포함한 비교는 항상 false가 된다.
- 동등(==)과 일치(===) 연산자:
==
는 형변환을 허용해 예상치 못한 결과를 초래할 수 있다.===
는 형변환 없이 값과 자료형이 모두 같을 때만 true를 반환한다. 일반적으로===
를 사용하는 것이 안전하다.
명시적인 형변환과 일치 연산자로 안전한 코드 작성하기
자바스크립트의 자동 형변환 덕분에 코드가 유연하게 작동하지만, 명시적으로 형변환을 수행하고, 비교에서는
===
연산자를 사용하는 것이 코드의 안정성을 높이는 방법이다.