[JS] 4. 타입 변환과 단축 평가

Joo·2024년 6월 17일
0

JavaScript

목록 보기
4/7
post-thumbnail

1. 타입 변환

타입 변환에는 크게 2가지가 있다.
JS 엔진이 값이 쓰이는 상황에 따라 타입 변환을 하는 암묵적 타입 변환
개발자가 의도적으로 타입 변환을 하는 명시적 타입 변환

1.1 암묵적 타입 변환

var str = 1 + '2';
console.log(str); // '12'

위의 예시에서 str 을 출력해보면 '12' 로 문자열 타입으로 출력된다.
분명 숫자 1문자열 2 를 더했으나, JS 엔진은 + 기호를 문자열 연결 연산자로 해석해 숫자 1문자열 1 로 암묵적인 타입 변환을 해 연산한 것이다.

암묵적인 타입 변환의 대표적인 예시들을 알아보자.

1.1.1 숫자 타입으로 변환

+ 기호를 제외한 나머지 산술 연산자는 숫자를 계산하기 위해 사용하는 연산자이므로 피연산자는 숫자 타입이어야 한다. 따라서 JS 엔진은 숫자 타입으로 암묵적 변환을 한다.
만약 숫자로 변환이 어려운 피연산자는 계산을 할 수 없으므로 표현식의 결과가 NaN 이 된다.

1 - '1'; // 0
1 * '10'; // 10
1 / ''; // Infinity
1 / 'hi'; // NaN

숫자와 비교하는 표현식 역시 문자역 1 을 숫자로 타입 변환을 해 비교한다.

'1' > 0; // true

+ 단항 연산자 를 숫자가 아닌 피연산자 앞에 붙이면 해당 피연산자를 숫자 타입으로 변환한다.

+'1'; // 1
+''; // 0
+'hi'; // NaN

+null; // 0

+undefined; // NaN

+true; // 1
+false; // 0

+Symbol(); // TypeError

+{}; // NaN
+[]; // 0
+[10, 20]; // NaN
+(function(){}); // NaN

1.1.2 문자열 타입으로 변환

위에서 언급했듯, + 연산자가 하나 이상의 문자열이 있는 표현식에 사용되면 문자열 연결 연산자 로 사용된다. 이 때, 문자열 타입으로 피연산자를 변환한다.

1 + ''; // '1'
NaN + ''; // 'NaN'
Infinity + ''; // 'Infinity'
-11 + ''; // '-11'

true + ''; // 'true'
false + ''; // 'false'

null + ''; // 'null'

undefined + ''; // 'undefined'

(Symbol()) + ''; // TypeError

({}) + ''; // '[obejct Object]'
[] + ''; // ''
[1, 2] + ''; // '1, 2'
(function(){}) + ''; // 'function(){}'
Array + ''; // 'function Array() { [native code] }'

1.1.3 불리언 타입으로 변환

if문이나 삼항 조건 연산자와 같은 조건식이 필요한 표현식은 true/false 값이 필요하다.
JS 엔진은 조건식에 true/false가 아닌 값이 있을 경우 Truthy 값(참으로 평가되는 값) Falsy 값(거짓으로 평가되는 값) 으로 판단할 수 있도록 암묵적인 타입 변환을 한다.

특히 Falsy 로 판단되는 값들을 기억하면 좋다.

  • undefined
  • null
  • 0 / -0
  • NaN
  • '' (빈 문자열)
// Truthy
if (1) ~
if ('hi') ~
  
// Falsy
if (undefined) ~
if (null) ~
if (0) ~
if (NaN) ~
if ('') ~

이러한 불리언으로 암묵적인 타입 변환을 하는 대표적인 예시가 짝수, 홀수를 판단할 때이다. 만약 짝수이면 2로 나눈 나머지가 항상 0 이므로 Falsy 값으로 타입 변환된다.

var x = 2;

if (x % 2) console.log(`${x}는 홀수`);
else console.log(`${x}는 짝수`); // 2는 짝수

1.2 명시적 타입 변환

개발자가 의도적으로 타입 변환을 하기 위해 명시적인 타입 변환을 만드는 방법 3가지가 있다.

  • 표준 빌트인 생성자 함수 ex) String, Number, Boolean
  • 빌트인 메서드 ex) toString()
  • 암묵적 타입 변환

1.2.1 문자열 타입으로 변환하기

  • String 생성자 함수를 사용하기
  • Object.prototype.toString() 메서드 사용하기
  • 문자열 연결 연산자 사용하기
String(1); // '1'
String(Infinity); // 'Infinity'
String(true); // 'true'

(11).toString(); // '11'
(false).toString(); // 'false'

1 + ''; // '1'
NaN + ''; // 'NaN'
true + ''; // 'true'

1.2.2 숫자 타입으로 변환하기

  • Number 생성자 함수 사용하기
  • parseInt, parseFloat 함수 사용하기 (단, 문자열만 숫자 타입으로 변환 가능)
  • + 단항 연산자 사용하기
  • 산술 연산자 사용하기
Number('123'); // 123
Number('NaN'); // NaN
Number(true); // 1

parseInt('-1'); // -1
parseInt('-1.1'); // -1
parseFloat('12.12'); // 12.12

+'0'; // 0
+'NaN'; // NaN
+true; // 1
+null; // 0

'1' * 10; // 10
false * 1; // 0

1.2.3 불리언 타입으로 변환하기

  • Boolean 생성자 함수 사용하기
  • !! 부정 논리 연산자 사용하기
Boolean('hi'); // true
Boolean(0); // false
Boolean(null); // false
Boolean(undefined); // false
Boolean(''); // false

Boolean({}); // true
Boolean([]); // true

!!'x'; // true
!!''; // false
!!1; // true
!!NaN; // false
!!null; // false
!!undefined; // false

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

2. 단축 평가

단축 평가는 논리 합(||), 논리 곱(&&)으로 이루어진 표현식에서 평가 결과가 논리적인 참/거짓 값으로 확정되어 이후 평가를 생략하는 것을 의미한다.
또한 피연산자가 타입 변환되지 않고 원래 값대로 반환되기 때문에 피연산자 둘 중 하나의 값으로 평가된다.

단축 평가 규칙

  • true || anything => true
  • false || anything => anything
  • true && anything => anything
  • false && anything => false

2.1 논리 합

논리 합의 경우 OR 연산이므로 피연산자 둘 중 하나만 true로 평가되어도 true를 반환한다.
즉, 첫번째 피연산자가 true이면 두번째 피연산자를 확인할 필요가 없으므로 첫번째 피연산자를 반환한다.

'Cat' || 'Dog'; // 'Cat'

2.2 논리 곱

논리 곱의 경우 AND 연산이므로 피연산자 모두 true로 평가되어야 true를 반환한다.
즉, 첫번째 피연산자가 true이면 두번째 피연산자의 값에 따라 결과가 평가되므로 두번째 피연산자의 값이 반환된다.

'Cat' && 'Dog'; // 'Dog'

2.3 단축 평가 사용 예시

2.3.1 객체가 null 또는 undefined인지 판단한 후 프로퍼티 값 참조하기

만약 car 라는 변수에 number 라는 프로퍼티 값을 참조하기 위해서는 먼저 car 가 가리키는 주소의 값에는 객체가 존재해야 한다.
car 값이 null 또는 undefined 이면 단축 평가를 통해 논리 곱 연산자 뒤의 프로퍼티를 참조하지 않는다.
즉, null 또는 undefined 값이 반환되므로 프로퍼티를 참조하지 못하는 타입 에러를 방지할 수 있다.

var car = null;

var carNumber = car.number; // TypeError

var carNumber = car && car.number; // null

2.3.2 함수 매개변수에 값을 전달하지 않을 경우

함수를 호출할 때 매개변수에 어떤 값도 전달하지 않으면 undefined 가 매개변수에 할당된다.
undefined 가 할당됨에 따라 발생할 수 있는 에러를 해결하기 위해 단축 평가를 사용할 수 있다.

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

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

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

2.3.3 옵셔널 체이닝 연산자

ES11부터 옵셔널 체이닝 연산자 ?. 을 피연산자 뒤에 사용하면 피연산자가 null 이나 undefined 일 경우 연산자 뒤의 프로퍼티를 참조하지 않고 undefined 를 반환한다.

var car = null;

var carNumber = car?.number; // undefined

위에서 설명한 논리 곱 && 를 객체의 프로퍼티를 참조하는 것과 다른 점은 연산자 앞 피연산자가 falsy 값일 경우 해당 값을 그대로 반환하지만 ?. 는 피연산자 falsy 값이여도 null 이나 undefined 인 경우가 아니면 프로퍼티를 참조한다.

var str = '';

var length = str && str.length; // ''

var length = str?.length; // 0

2.3.4 null 병합 연산자

ES11부터 null 병합 연산자 ?? 를 사용할 수 있다. 연산자 앞의 피연산자가 null 이나 undefined 이면 뒤의 피연산자가 반환되고, 아니면 앞의 피연산자가 반환된다.

var value = null ?? 'default value'; // default value

논리 합 || 과 다른 점은 논리 합 연산자 앞의 피연산자 값이 falsy 이면 뒤의 피연산자 값이 반환되는 반면 ?? 연산자는 앞의 피연산자가 null 이나 undefined 가 아닌 falsy 값이면 앞의 피연산자를 그대로 반환한다.

var str = '';

var value = str ?? 'default value'; // ''

주의할 점은 0 이나 '' 같은 값이 유효한 값으로 여길 경우 논리 합 || 을 사용할 때 문제가 발생할 수 있다.

profile
한 줄이 모여 책이 되듯 기록하기

0개의 댓글