Modern JavaScript Deep Dive 9장

younghyun·2022년 5월 14일

타입 변환과 단축 평가

표현식이 어떻게 평가될지 예측이 가능해야 함. 예측이 결과와 일치하지 않는다면 오류를 생산할 가능성이 높아짐.

명시적 타입 변환

개발자가 의도적으로 값의 타입을 변환하는 것

var x = 10;

// 명시적 타입 변환
// 숫자를 문자열로 타입 캐스팅
var str = x.toString();
console.log(typeof str, str); // string 10

// x 변수의 값이 변경된 것은 아니다.
console.log(typeof x, x); // number 10
  • 문자열 타입으로 변환
    string 생성자 함수를 new연산자 없이 호출하는 방법
    Object.prototype.toString메서드 사용하는 방법
    문자열 연결 연산자 이용하는 방법

  • 숫자 타입으로 변환
    Number생성자 함수를 new연산자 없이 사용하는 방법
    parseInt, parseFloat함수를 사용하는 방법(문자열만 숫자 타입으로 변환 가능)
    +단항 산술 연산자 이용하는 방법
    *산술 연산자를 이용하는 방법

  • 불리언 타입으로 변환
    Boolean 생성자 함수를 new연산자 없이 호출하는 방법
    !부정 논리 연산자를 두 번 사용하는 방법

암묵적 타입 변환(타입 강제 변환)

개발자 의도와 상관없이 표현식 평가하는 도중 자바스크립트 엔진이 암묵적으로 타입 변환

var x = 10;

// 암묵적 타입 변환
// 문자열 연결 연산자는 숫자 타입 X의 값을 바탕으로 새로운 문자열을 생성
var str = x + '';
console.log(typeof str, str); // string 10

// x 변수의 값이 변경된 것은 아니다.
cnosole.log(typeof x, x); // number 10

원시 값은 변경 불가능한 값.
위 예제에서 자바스크립트 엔진은 표현식 x + ''을 평가하기 위해 x변수(피연산자)의 숫자 값을 바탕으로 암묵적으로 새로운 타입(문자열) 값 '10'을 생성하고 이것으로 표현식 평가함. 암묵적으로 생성된 문자열 10은 x변수에 재할당 되지 않고, 한 번 사용하고 버림.(기존 원시 값을 직접 변경하는 게 아님.)

  • 문자열 타입으로 변환
    +연산자는 피 연산자중 하나 이상이 문자열이면 문자열 연결 연산자로 동작함.
    문자열 연결 연산자 역할은 문자열 값을 만드는 것. 문자열 연결 연산자 모든 피연산자는 코드 문맥상 모두 문자열 타입이어야 함.
1 + '2' // 12

자바스크립트 엔진은 표현식을 평가할 때 코드 문맥에 부합하도록 암묵적 타입 변환 실행함. 템플릿 리터럴 표현식 삽입 시 표현식 평가 결과를 문자열 타입으로 암묵적 타입 변환함.

`1 + 1 = ${1+1}`// -> "1 + 1 = 2"
// 숫자 타입
0 + '' // "0"
-0 + '' // "0"
1 + '' // "1"
-1 + '' // "1"
NaN + '' // "NaN"
Infinity + '' // "Infinity"
-Infinity + '' // "-Infinity"

// 불리언 타입
true + '' // "true"
false + '' // "false"

// null 타입
null + '' // "null"
 
// undefined 타입
undefined + '' // "undefined"

// 심벌 타입
(Symbol()) + '' // TypeError 

// 객체 타입
({}) + '' // "[object Obejct]"
Math + '' // "[object Math]"
[] + '' // ""
[10, 20] + '' // "10, 20"
(function(){}) + '' // "function(){}"
Array + '' // "function Array(){[native code]}"
  • 숫자 타입으로 변환
    산술 연산자 역할은 숫자 값 만드는 것. 모든 피연산자는 숫자 값. 숫자 값 아닐 경우 암묵적 타입 변환. 변환 할 수 없는 경우 산술 연산 수행이 안되므로 결과값으로 NaN 반환.
1 - '1' // 0
1 * '10' // 10
1 / 'one' // NaN

// 문자열 타입
+'' // 0
+'0' // 0
+'1' // 1
+'string' //NaN

// 불리언 타입
+true // 1
+false // 0

// null 타입
+null // 0

// undefined 타입
+undefined // NaN 

// 심벌 타입
+Symbol() // TypeError

// 객체 타입
+{} // NaN
+[] // 0
+[10, 20] // NaN
+(function(){}) // NaN

빈 문자열(''), 빈 배열([]), null, false는 0으로, true는 1로 변환됨. 객체, 빈 배열이 아닌 배열, undefined는 변환이 되지 않아 NaN이 됨.

비교 연산자 역할은 불리언 값 만드는 것. 모든 피 연산자는 숫자 값. 숫자 값 아닐 경우 암묵적 타입 변환.

'1' > 0 // true
  • 불리언 타입으로 변환
    제어문, 삼항 조건 연산자 조건식은 불리언 값, 논리적 참/거짓으로 평가되어야 하는 표현식
    자바스크립트 엔진은 평가 결과를 불리언 타입으로 변환함. 불리언 타입이 아닌 값은 Truthy, Falsy로 구분함. 불리언 값으로 평가되어야 할 문맥에서 Truthy는 true, Falsy는 false로 암묵적 타입변환
if('') console.log('1');
if(true) console.log('2')'
if(0) console.log('3');
if('str') console.log('4');
if(null) console.log('5');

// 2 4
False로 평가되는 Falsy값
false
undefined
null
0, -0
NaN
''(빈 문자열)

// 모두 true 반환
funtion isTruthy(v) {
	return !!v;
}

isTruthy(true);
isTruthy('0'); // 빈 문자열이 아닌 문자열은 Truthy값
isTruthy({});
isTruthy([]);

단축 평가

  • 논리 연산자를 사용한 단축 평가
    논리 합(||), 논리 곱(&&)연산자 평가 결과는 2개의 피연산자 중 어느 한쪽으로 평가됨.

논리곱 연산자
두 개 피연산자가 모두 true일 때 true, 좌항에서 우항으로 평가 진행, 연산의 결과를 결정하는 피연산자를 그대로 반환함.
좌항 피연산자가 false값으로 평가되는 Falsy 값(false, undefined, null, 0, -0, NaN, '')이면 좌항 피연산자 그대로 반환함.

논리합 연산자
두 개 피연산자 중 하나만 true여도 true반환, 좌항에서 우항으로 평가 진행,
연산 결과를 결정하는 피연산자 그대로 반환함.

// 논리합(||) 연산자
'Cat' || 'dog' // 'Cat'
false || 'Dog' // 'Dog'
'Cat' || fasle // 'Cat'

조건이 Falsy 값(거짓으로 평가되는 값)일 때 논리합(||)연산자 표현식으로 if문 대체
var done = false;
var message = '';

// 주어진 조건이 false일 때
if (!done) message = '미완료';

// if문은 단축 평가로 대체 가능
// done이 false라면 message에 '미완료'를 할당
message = done || '미완료';
console.log(message); // 미완료

// 논리곱(&&) 연산자
'Cat' && 'Dog' // 'Dog'
false && 'Dog' // false
'Cat' && false // false

조건이 Truthy 값(참으로 평가되는 값)일 때 논리곱(&&)연산자 표현식으로 if문 대체 
var done = true;
var message = '';

// 주어진 조건이 true일 때
if (done) message = '완료';

// if문은 단축 평가로 대체 가능
// done이 true라면 message에 '완료'를 할당
message = done && '완료';
console.log(message); // 완료

삼항 조건 연산자는 if...else문 대체 가능

var done = true;
var message = '';

// if...else 문
if (done) message = '완료';
else      message = '미완료';
console.log(message); // 완료

// if...else 문은 삼항 조건 연산자로 대체 가능
message = done ? '완료' : '미완료';
console.log(message); // 완료

객체가 가리키기를 기대하는 변수가 null 또는 undefined가 아닌지 확인하고 프로퍼티 참조할 때

var elem = null;
var value = elem.value // TypeError

var elem = null;
var value = elem && elem.value // null

함수 매개변수에 기본값을 설정할 때

funtion getStringLength(str) {
	str = str || '';
    return str.length;
}

getStringLength(); // 0
getStringLength('hi'); // 2
  • 옵셔널 체이닝 연산자(?.)
    좌항의 피연산자가 false값으로 평가되는 Falsy값(false, undefined, null, 0, -0, NaN, '') 중 null 또는 undefined인 경우 undefined반환 그렇지 않으면 우항의 프러피티 참조 이어감.
    객체를 가리키기를 기대하는 변수가 null 또는 undefined가 아닌지 확인하고 프로퍼티 참조할 때 유용.
var elem = null;

var value = elem?.value;
console.log(vlaue);// undefined;
  • null 병합 연산자(??)
    좌항의 피연산자가 false로 평가되는 Falsy 값(false, undefined, null, 0, -0, NaN, '')이라도 null 또는 undefined가 아니면 좌항의 피연산자 그대로 반환
var foo = null ?? 'default string';
console.log(foo); // 'default string'

// Falsy 값인 0이나 ''도 기본값으로서 유효하다면 예기치 못한 동작이 발생할 수 있다.
var foo = '' || 'default string';
console.log(foo); // 'default string'

// 좌항의 피연산자가 Falsy값이라도 null 또는 undefined가 아니면 좌항의 피연산자 그대로 반환
var foo = '' ?? 'default String';
console.log(foo); // ''
profile
선명한 기억보다 흐릿한 메모

0개의 댓글