header wave

Post

JS) 타입 변환과 단축 평가

2022-09-20 AM 07/00
#javascript
#study

타입 변환이란

자바스크립트의 모든 값은 타입이 있다. 값의 타입은 다른 타입으로 변환할 수 있다. 개발자의 의도적을 값의 타입을 변환하는 것을 명시적 타입 변환(explicit coercion) 또는 타입 캐스팅 이라 한다.

개발자의 의도와는 상관없이 표현식을 평가하는 도중에 자바스크립트 엔진에 의해 암묵적으로 타입이 자동 변환되기도 한다. 이를 암묵적 타입 변환(implicit coercion) 또는 타입 강제 변환이라 한다.

명시적 타입 변환이나 암묵적 타입 변환이 기존 원시 값을 직접 변경하는 것은 아니다. 원시 값은 변경 불가능한 값이므로 변경할 수 었다.

타입 변환이란 기존 원시 값을 사용해 다른 타입의 새로운 원시 값을 생성하는 것이다.

암묵적 타입 변환

'10' + 2// '102' 피연산자가 모두 문자열 타입이어야 하는 문맥5 * '10'// 50 피연산자가 모두 숫자 타입이어야 하는 문맥

!0// true 피연산자 또는 표ㅕㄴ식이라 불리언 타입이어야 하는 문맥if(1) {}

  1. 문자열 타입으로 변환

자바스크립트 엔진은 문자열 연결 연산자 표현식을 평가하기 위해 문자열 연결 연산자의 피연산자 중에서 문자열 타입이 아니면 피연산자를 문자열 타입으로 암묵적 타입 변환한다.

// 숫자타입0 + ''// "0"NaN + ''// "NaN"Infinity + ''// "Infinity"//불리언 타입true + ''// 'true'//null 타입null + ''// 'null'//undefined 타입undefined + ''// 'undefined'// 심벌타입
(Symbol()) + ''// TypeError: cannot conver a Symbol value to string//객체타입
({}) + ''// "[object + object]"Math + ''// [object Math]

[] + ''// ""
[10,20] + ''// "10,20"function(){} + ''// "function() {}"Array + ''// "function Array() {[native code]}"

  1. 숫자 타입으로 변환

1 - '1'// 01 * '10'// 101 / 'one'// NaN'1' > 0// true

비교 연산자의 역할을 불리언 값을 만드는 것이다. > 비교 연산자는 피연자의 크기를 비교하므로 모든 피연자는 코드 문맥상 모두 숫자 타입이어야 한다.

// 문자열 타입
+''// 0
+'0'// 0
+'1'// 1
+'string'//NaN// 불리언 타입
+true// 1
+false// 0// null 타입
+null//0// undefined 타입
+undefined//  NaN// 심벌타입
+Symbol()// TypeError: Cannot convert a Sybol value to a number// 객체타입
+{}// NaN
+[]// -
+[10,20]//  NaN
+(function(){})// NaN

불리언 타입으로 변환

false, undefined, null, 0, -0, NaN, ''(빈문자열) : 모두 falsy 값이다.

명시적 타입 변환

표준 빌트인 생성자 함수 (String, Number, Boolean)를 new 연산자 없이 호출하는 방법과 빌트인 메서드를 사용하는 방법, 그리고 앞에서 살펴본 암묵적 타입변환을 이용하는 방법이 있다.

  1. 문자열 타입으로 변환
  • String 생성자 함수를 new 연산자 없이 호출하는 방법
  • Object.prototype.toString 메서드를 사용하는 방법
  • 문자열 연결 연산자를 이용하는 방법

// 1) String 생성자 함수를 new 연산자 없이 호출하는 방법String(1)// '11String(NaN)//  "NaN"String(Infinity)// "Infinity"String(true)// "true"String(false)// "false"// 2) Object.prototype.toString 메서드를 사용하는 방법
(1).toString();// "1"
(NaN).toString();// "NaN"
(Infinity).toString();//"Infinity"
(true).toString();// "true"
(false).toString();// "false"// 3) 문자열 연결 연산자를 이용하는 방법1 + '';// "1"NaN + ''// "NaN"Infinity + '';// "Infinity"true + '';// "true"false + '';// "false"

  1. 숫자 타입으로 변환

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

// 1) Number 생성자 함수를 new 연산자 없이 호출하는 방법Number('0');// 0Number('-1');// -1Number('10.53')// 10.53Number(true)// 1Number(false)// 0// 2) parseInt, parseFloat 함수를 사용하는 방법 (문자열만 숫자 타입으로 변환가능)parseInt('0')// 0// 3) +단항 산술 연산자를 이용하는 방법
+'0';// 0
+'-1'// -1

+true// 1
+false// 0// 4) *산술 연산자를 이용하는 방법'0' * 1// 0'10.53' * 1// 10.53true * 1;// 1false * 1;// 0

  1. 불리언 타입으로 변환

  • Boolean 생성자 함수를 new 연산자 없이 호출하는 방법
  • ! 부정 논리 연산자를 두 번 사용하는 방법

// 1) Boolean 생성자 함수를 new 연산자 없이 호출하는 방법Boolean('x');// trueBoolean('');// falseBoolean('false')// trueBoolean(0);// falseBoolean(1);// trueBoolean(NaN)// falseBoolean(Infinity);  true

Boolean(null);// falseBoolean(undefined)// falseBoolean({})// trueBoolean([])// true// 2) ! 부정 논리 연산자를 두 번 사용하는 방법

!!'x';// true
!!'';// false
!!'false';//false

!!0;// false
!!1;// true
!!NaN;// false
!!Infinity;// true

!!null;// false

!!undefined;// false

!!{};// true
!![];// true

단축 평가

논리합(||) 또는 논리곱(&&) 연산자의 표현 평가 결과는 불리언 값이 아닐 수도 있다.

2개의 피연산자 중 어느 한쪽으로 평가된다.

'Cat'&& 'Dog'//"Dog"

논리곱(&&) 연산자는 두 개의 피 연산자가 모두 true로 평가 될 때 true를 반환한다. 논리곱 연산자는 좌항에서 우항으로 평가가 진행된다.

첫번째 피연산자 'Cat'은 Truthy값이므로 true로 평가된다. 하지만 이 시점까지는 위 표현식을 평가할 수 없다. 두번쨰 피연산자까지 평가해 보아야 위 표현식을 평가할 수 있다.

논리곱 연산자는 논리 연산의 결과를 결정하는 두 번째 피연자, 즉 문자열'Dog'를 그대로 반환한다.

'Cat' || 'Dog'// "Cat"

논리합(||) 연산자는 두 개의 피연산자 중 하나만 true로 평가 되어도 true로 반환한다.

피연산자 'Cat'이 true 이므로 'Cat'을 반환한다.

'Cat' || 'Dog'// "Cat"false || 'Dog'// "Dog"'Cat' || false// "Cat"'Cat' && 'Dog'// 'Dog'false && 'Dog'// false'Cat' &&  false// false

단축 평가를 사용하면 if 문을 대체할 수 있다. 어떤 조건이 Truthy 값(참으로 평가되는 값)일 때 무언가를 해야 한다면 (&&) 연산자 표현식으로 if문을 대체할 수 있다.

var done =  true;
var message = '';

if (done) message = '완료';

message = done && '완료';
console.log(message);// 완료

조건이 Falsy값을 해야한다면 논리합 연산자로 if문을 대체할 수 있다.

var done = 'false';
var message = '';

if (!done) message = '미완료';

message = done || '미완료';
console.log(message);// 미완료

단축 평가는 다음과 같은 상황에서 유용하게 사용된다.

  1. 객체를 가리키기를 기대하는 변수가 null 또는 undefined가 아닌지 확인하고 프로퍼티를 참조할때
var elem = null;
var value = elem.value;// TypeError: Cannot read property'value' of nullvar elem = null;
var value = elem && elem.value;// null// elem이 null 이나 undefined와 값은 Falsy 값이면 elem으로 평가되고// elem이 Truthy 값이면 elem.value 값으로 평가된다.
  1. 함수 매개변수에 기본값을 설정할 떄
function() getStringLength(str) {
str = str || '';
return str.length;
}

getStringLength();// 0
getStringLength('hi');// 2// ES6의 매개변수의 기본값 설정function() getStringLength(str = '') {
	return str.length;
}

getStringLength();// 0
getStringLength('hi');// 2

옵셔널 체이닝 연산자 (?.)

ES11에서 도입된 옵셔널 체이닝 연산자 ?.는 좌항의 피연산자가 null 또는 undefined일 경우 undefined를 반환하고, 그렇지 않으면 우항의 프로퍼티 참조를 이어간다.

var elem = null;

var value = elem?.value;
console.log(value)// undefined

옵셔널 체이닝 연산자 ?. 는 객체를 가리키기를 기대하는 변수가 null 또는 undefined가 아닌지 확인하고 프로퍼티를 참조할 때 유용하다. 옵셔널 체이닝 연산자 ?. 가 도입되기 이전에는 논리연산자 &&를 사용한 단축 평가를 통해 null 또는 undefined 인지 확인했다.

var elem = null;

// elem이 Falsy 값이면 elem으로 평가되고, elem이 Truthy값이면 elem.value로 평가된다.var value = elem && elem.value;
console.log(value);// null

논리연산자 &&는 좌항 피연산자가 false로 평가되는 (false, undefined, null, 0, -0, NaN, ''") 이면 좌항 피연산자를 그대로 반환한다.

var str = '';

var length = str && str.length;

console.log(length);// ''

하지만 옵셔널 체이닝 연산자 ?. 는 좌항 피연산자가 false로 평가가 되더라도 null 또는 undefined가 아니면 우항의 프로퍼티 참조를 이어간다.

var str = '';

var length = str?.length

console.log(length);// 0

null 병합 연산자 ??

ES11에서 도입된 null 병합 연산자 ??는 좌항의 피연산자가 null 또는 undefined인 경우 우항의 피연산자를 반환하고, 그렇지 않으면 좌항의 피연산자를 반환한다. null 병합 연산자 ??는 변수에 기본값을 설정할 때 유용하다.

var foo = null ?? 'default string';
console.log(foo);// "default string"

null 병합 연산자 ?? 는 변수에 기본값을 설정할 때 유용하다. null 병합 연산자 ??가 도입되기 이전에는 논리 연산자 || 를 사용한 단축 평가를 통해 변수에 기본값을 설정했다.

논리 연산자 || 를 사용한 단축 평가의 경우 좌항의 피연산자가 false로 평가되는 (false, undefined, null, 0, -0, NaN, ''") 이면 우항의 피연산자를 반환한다. 만약 Falsy 값인 0이나 ''도 기본값으로서 유효하다면 예기치 않은 동작이 발생할 수 있다.

var foo = '' || 'default string';
console.log(foo);// "default string"

하지만 null 병합 연산자 ??는 좌항이 피연산자가 false로 평가되는 Falsy 값 (false, undefined, null, 0, -0, NaN, ''") 이라도 null 또는 undefined가 아니면 좌항의 피연산자를 그대로 반환하다.

var foo = '' ?? 'default string';
console.log(foo);// ""
let current;

function f() {
  let result = current ?? getNum();
  console.log(result);
}