Modern JavaScript Deep Dive 9장

younghyun·2022년 5월 14일
0

타입 변환과 단축 평가

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

명시적 타입 변환

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

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개의 댓글