var x = 10;
var str = x + ''; // 암묵적 타입 변환
console.log(typeof str, str); // string 10
위의 코드에서, x
변수의 숫자 값을 바탕으로 새로운 문자열 '10'
값을 생성한다.
JS 엔진은 표현식을 에러 없이 평가하기 위해 값을 암묵적으로 타입을 변환하여 새로운 타입의 값을 생성한다.
이렇게 드러나지 않게 타입이 자동 변환되기 때문에, 타입을 변경하겠다는 개발자의 의지가 코드에 명백히 나타나지 않는다.
따라서 자신이 작성한 코드에서 암묵적 타입 변환이 발생하는지, 발생한다면 어떤 타입의 어떤 값으로 변환되는지 예측 가능해야 한다.
개발자가 의도적으로 타입을 변경하는 방법은 다양하다.
- 표준 빌트인 생성자 함수(String, Number, Boolean)를 new 연산자 없이 호출
- 빌트인 메서드 사용
- 암묵적 타입 변환 사용
📙 표준 빌트인 생성자 함수를 new 연산자 없이 호출하는 방법
String(1); // "1"
String(true); // "true"
Number('0'); // 0
Number(false); // 0
Boolean('x'); // true
Boolean(0); // false
Boolean(null); // false
📙 빌트인 메서드를 사용하는 방법
(1).toString(); // "1"
(true).toStirng(); // "true"
parseInt('0'); // 0
parseFloat('10.53'); // 10.53
📙 암묵적 타입 변환을 사용하는 방법
1 + ''; // "1"
true + ''; // "true"
+'-1'; // -1
'-1' * 1 // -1
true * 1 // 1
!!'x'; // true
!! ''; // false
!!'false'; // true
!!null; // false
'Cat' && 'Dog' // 'Dog'
'Cat' || 'Dog' // 'Cat'
첫 번째 표현식의 경우, 첫 번째 피연산자 Cat
은 true
로 평가되지만 두 번째 피연산자까지 평가를 해봐야 위 표현식을 평가할 수 있다.
두 번째 표현식에서는 첫 번째 Cat
이 true
로 평가되기 때문에 두 번째 피연산자까지 평가해보지 않아도 위 표현식을 평가할 수 있다.
** 논리 연산자로 false라 평가되는 값: false, undefined, null, 0, -0, NaN, ''
단축평가(short-circuit evaluation)란, 표현식을 평가하는 도중에 평가 결과가 확정된 경우 나머지 평가 과정을 생략하는 것을 말한다.
// 논리곱 && 연산자
'Cat' && 'Dog' // 'Dog'
false && 'Dog' // false
'Cat' && false // false
// 논리합 || 연산자
'Cat' || 'Dog' // 'Cat'
false || 'Dog' // 'Dog'
'Cat' || false // 'Cat'
또한 논리곱 &&
과 논리합 ||
연산자는 논리 연산의 결과를 결정하는 피연산자를 타입 변환하지 않고 그대로 반환하는 것을 알 수 있다.
📙 첫 번째, if 문을 대체할 때
var done = true;
var message = '';
if(done) message = '완료';
// 단축 평가 사용
message = done && '완료'; // done이 true 라면 '완료'를 할당
var done = false;
var message = '';
if(!done) message = '미완료';
// 단축평가 사용
message = done || '미완료'; // done이 false라면 '미완료'를 할당
📙 두 번째, null 또는 undefined가 아닌지 확인하고 프로퍼티를 참조할 때
var elem = null;
var value = elem.value; // error
// elem이 null이나 undefined면 elem으로 평가되고 그렇지 않으면 elem.value로 평가
var value = elem && elem.value; // null
📙 세 번째, 함수 매개변수에 기본값을 설정할 때
function getStringLength(str) {
str = str || ''; // 매개 변수가 없을 때는 undefined가 할당되면서 str의 기본값을 ''으로 설정
return str.legnth;
}
getStringLength(); // 0
getStringLength('hi'); // 2
ES11(ECMAScript 2020)에 도입된 옵셔녈 체이닝(Optional chaining) 연산자
?.
과 null 병합(nullish coalescing) 연산자??
가 바로 그것이다.
논리 연산자를 이용해서 구현했을 때 의도와 다르게 표현되는 경우가 있다. 다음의 경우를 보자.
var str = '';
var length = str && str.length;
console.log(length); // ''
str
의 길이를 나타내는 코드를 작성하고자 했는데, 논리 연산자의 경우 ''
값 또한 false
라 평가받기 때문에 str
이 빈 스트링일 경우 정상적인 값을 받을 수 없다.
옵셔널 체이닝 연산자 ?.
를 사용하면 해당 예제를 의도대로 작성할 수가 있는데,
옵셔널 체이닝 연산자
?.
는 좌항의 피연산자가 null 또는 undefined인 경우undefined
를 반환하고 그렇지 않으면우항의 프로퍼티
참조를 이어간다.
위의 예제를 ?.
를 사용해 다시 작성하면 다음과 같다.
var str = '';
var length = str?.length;
console.log(length); // 0
즉, ''
이라도 null이나 undefined가 아니기 때문에 프로퍼티 참조를 이어갈 수 있는 것이다.
null 병합 연산자
??
는 좌항의 피연산자가 null 또는 undefined인 경우우항의 피연산자
를 반환하고, 그렇지 않으면좌항의 피연산자
를 반환한다.
먼저 null 병합 연산자가 아닌 논리 연산자를 이용했을 때를 보면,
var foo = 0;
console.log(foo || 10); // 10
foo
변수에 0
을 할당했지만 0
을 falsy한 값으로 취급하기 때문에 null
이나 undefined
를 할당한 것과 동일하게 처리되어 10
을 반환되었다.
이렇게 ||
연산자를 사용하는 경우, 예기치 않은 동작이 발생할 수 있다.
위의 예제를 null 병합 연산자로 다시 작성하면 다음과 같다.
var foo = 0;
console.log(foo ?? 10); // 0
좌항의 피연산자가 null 또는 undefined일 경우에만 10
을 반환하기 때문에, 그렇지 않은 경우에는 좌항의 피연산자인 0
을 그대로 반환하는 것을 볼 수있다.
null 병합 연산자를 이용하면 변수에 기본값을 설정할 때 유용하게 사용할 수 있다.