가오리의 코딩일기
9장 타입 변환과 단축 평가 본문
💡 암묵적 타입 변환(implicit coercion), 타입 강제 변환(type coercion)
→ 자바스크립트 엔진은 표현식을 평가할 때 코드 문맥에 부합하도록 자동 변환 수행
→ 재할당이 아닌 새로운 타입의 값을 만들어 단 한 번 사용하고 버린다
→ 표현식을 에러 없이 평가하기 위해서
🧩 문자열 타입으로 변환
→ +연산자는 피연산자 중 문자열이 존재하면 문자열 연결 연산자로 동작한다
→ 템플릿 리터럴의 표현식 삽입: 표현식의 평가 결과를 문자열 타입으로 암묵적 타입 변환한다
`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: Cannot convert a Symbol value to a string
→ 객체 타입
({} + ""); // "{object Object}"
Math + ""; // "[object Math]"
[] + ""; // ""
[10, 20] + ""; // "10,20"
(function () {} + ""); // "function(){}"
Array + ""; // "function Array() { [native code }"
🧩 숫자 타입으로 변환
→ 피연산자를 숫자 타입으로 변환할 수 없을 때 평가 결과: NaN
→ 빈 문자열, 빈 배열, Null, false는 0, true는 1로, 배열, undefined는 NaN로 변환
→ 문자열 타입
+""; // 0
+"0"; // 0
+"1"; // 1
+"string"; // NaN
→ 불리언 타입
+true; // 1
+false; // 0
→ null 타입
+null; // 0
→ undefined 타입
+undefined; // NaN
→ 심벌 타입
+Symbol(); // TypeError: Cannot convert a Symbol value to a number
→ 객체 타입
+{}; // NaN
+[]; // 0
+[10, 20]; // NaN
+function () {}; // NaN
🧩 불리언 타입으로 변환
🔗 truthy: 참으로 평가되는 값
function isFalsy(v) {
return !v;
}
function isTruthy(v) {
return !!v;
}
// 모두 true를 반환한다
isFalsy(false);
isFalsy(undefined);
isFalsy(null);
isFalsy(0);
isFalsy(NaN);
isFalsy(" ");
// 모두 true를 반환한다
isTruthy(true);
isTruthy("0");
isTruthy({});
isTruthy([]);
→ truthy 값을 true로 변환하기 때문에 아래의 모든 if블록을 실행하게 된다
if (true)
if ({})
if ([])
if (42)
if ("0")
if ("false")
if (new Date())
if (-42)
if (12n)
if (3.14)
if (-3.14)
if (Infinity)
if (-Infinity)
🔗 falsy: 거짓으로 평가되는 값
💡 명시적 타입 변환(explicit coercion), 타입 캐스팅(type casting)
→ 개발자가 의도적으로 값의 타입을 변환하는 것
→ 방법1: 표준 빌트인 생성자 함수를 new 연산자 없이 호출
→ 방법2: 빌트인 메서드 사용
🔗 표준 빌트인 생성자 함수 vs. 빌트인 메서드
→ 모두 자바스크립트에서 기본 제공하는 함수
→ 표준 빌트인 생성자 함수: 객체 생성을 위한 함수, new 연산자와 함께 호출
→ 빌트인 메서드: 자바스크립트에서 기본 제공하는 빌트인 객체의 메서드
추가적인 설명은 21장에서 이어진다
🧩 문자열 타입으로 변환
→ String 생성자 함수를 new 연산자 없이 호출하는 방법
// 숫자 → 문자열
String(1); // "1"
String(NaN); // "NaN"
String(Infinity); // "Infinity"
// 불리언 → 문자열
String(true); // "true"
String(false); // "false"
→ Object.prototype.toString 메서드를 사용하는 방법
// 숫자 → 문자열
(1).toString(); // "1"
(NaN).toString(); // "NaN"
(Infinity).toString(); // "Infinity"
// 불리언 → 문자열
(true).toString(); // "true"
(false).toString(); // "false"
→ 문자열 연결 연산자를 이용하는 방법
// 숫자 → 문자열
1 + ""; // "1"
NaN + ""; // "NaN"
Infinity + ""; // "Infinity"
// 불리언 → 문자열
true + ""; // "true"
false + ""; // "false"
🔗 toString vs. String
→ 형변환만 할 때는 차이가 없다, 완전히 같은 결과
→ String()은 null, undefined에서 작동하지만 toString()은 아니다
→ toString() : 특정 진수로 객체를 표현한 문자열로 반환
→ String() : 문자로 형 변환하여 반환
let value = null;
String(value); // "null"
value.toString(); // TypeError: Cannot read properties of null (reading 'toString')
🧩 숫자 타입으로 변환
→ Number 생성자 함수를 new 연산자 없이 호출하는 방법
// 문자열 → 숫자
Number('0'); // 0
Number('-1'); // -1
Number('10.53'); // 10.53
// 불리언 → 숫자
Number(true); // 1
Number(false); // 0
→ parseInt, parseFloat 함수를 사용하는 방법(문자열만 숫자 타입으로 변환 가능)
// 문자열 → 숫자
parseInt('0'); // 0
passeInt('-1'); // -1
parseInt('10.53'); // 10
parseFloat('10.53'); // 10.53
→ +단항 산술 연산자를 이용하는 방법
// 문자열 → 숫자
+"0"; // 0
+"-1"; // -1
+"10.53"; // 10.53
// 불리언 → 숫자
+true; // 1
+false; // 0
→ *산술 연산자를 이용하는 방법
// 문자열 → 숫자
"0" * 1; // 1
"-1" * 1; // -1
"10.53" * 1; // 10.53
// 불리언 → 숫자
true * 1; // 1
false * 1; // 0
🔗 parseInt vs. Number
→ parseInt(value) : 숫자와 문자 중 정수만 인식하여 정수로 리턴한다[문자가 앞에 있는 경우 불가능]
→ Number(value) : 숫자로 이루어진 것만 숫자로 리턴(정수, 실수 모두 가능)
🧩 불리언 타입으로 변환
→ Boolean 생성자 함수를 new 연산자 없이 호출하는 방법
// 문자열 → 불리언
Boolean("x"); // true
Boolean(""); // false
Boolean("false"); // true
// 숫자 → 불리언
Boolean(0); // false
Boolean(1); // false
Boolean(Infinity); // true
// null → 불리언
Boolean(null); // false
// undefined → 불리언
Boolean(undefined); // false
// 객체 → 불리언
Boolean({}); // true
Boolean([]); // true
→ ! 부정 논리 연산자를 두 번 사용하는 방법
// 문자열 → 불리언
!!'x'; // true
!!''; // false
!!'false'; // true
// 숫자 → 불리언
!!0; // false
!!1; // true
!!NaN; // false
!!Infinity; // true
// null → 불리언
!!null; // false
// undefined → 불리언
!!undefined; // false
// 객체 → 불리언
!!{}; // true
!![]; // true
💡 단축 평가(short-circuit evaluation)
🧩 논리 연산자를 사용한 단축 평가
→ 논리합(||) 또는 논리곱(&&)의 평가 결과는 불리언 값이 아닐 수도 있다.
→ 논리합과 논리곱은 언제나 2개의 피연산자 중 어느 한쪽으로 평가된다.
→ 논리 연산의 결과를 결정하는 피연산자를 타입 변환하지 않고 그대로 반환한다
→ 표현식을 평가하는 도중에 평가 결과가 확정된 경우 나머지 평가 과정을 생략한다
✏️ 논리합(&&)
→ 두 개의 피연산자가 모두 true로 평가될 때 true를 반환한다
→ 좌항에서 우항으로 평가가 진행된다
'Cat' && 'Dog'; // "Dog"
→ 첫 번째 피연산자 ‘Cat’은 Truthy 값으로 true
→ 첫 번째 피연산자가 true이기 때문에 두 번째 피연산자까지 평가해 보아야 위 표현식을 평가할 수 있다
→ 논리 연산의 결과를 결정하는 두 번째 피연산자, 문자열 ‘Dog’를 그대로 반환한다
→ 어떤 조건이 Falsy 값일 때 논리합 연산자 표현식으로 if문을 대체할 수 있다
let done = true;
let message = '';
if(done) message = '완료';
message = done && '완료';
console.log(message); // 완료
✏️ 논리곱(||)
→ 두 개의 피연산자 중 하나만 true로 평가되어도 true를 반환한다
→ 마찬가지로 좌항에서 우항으로 평가가 진행된다
'Cat' || 'Dog'; // "Cat"
→ 첫 번째 피연산자 ‘Cat’은 Truthy 값으로 true
→ 첫 번째 피연산자가 true이기 때문에 두 번째 피연산자는 평가할 필요가 없다
→ 논리 연산의 결과를 결정하는 첫 번째 피연산자(’Cat’)를 그대로 반환한다
→ 어떤 조건이 Truthy 값일 때 논리곱 연산자 표현식으로 if문을 대체할 수 있다
let done = false;
let message = '';
if(!done) message = '미완료';
message = done || '미완료';
console.log(message); // 미완료
✏️ 객체를 가리키기를 기대하는 변수가 null 또는 undefined가 아닌지 확인하고 프로퍼티를 참조할 때
→ 객체: 키와 값으로 구성된 프로퍼티의 집합
→ 변수의 값이 객체가 아니라 null 또는 undefined인 경우 타입에러가 발생한다
let elem = null;
let value = elem.value; // TypeError: Cannot read property 'value' of null
let elem = null;
let value = elem && elem.value; // null
✏️ 함수 매개변수에 기본값을 설정할 때
→ 함수 호출 시 인수를 전달하지 않으면 매개변수에 undefined가 할당된다
→ 단축평가를 통해 매개변수의 기본값을 설정하면 undefined로 인해 발생할 에러를 방지한다
// 매개변수의 기본값 설정
function getStringLength(str = ''){
return str.length;
}
getStringLength(); // 0
getStringLength('hi'); // 2
// 단축평가를 사용한 매개변수의 기본값 설정
function getStringLength(str){
str = str || "";
return str.length;
}
getStringLength(); // 0
getStringLength('hi'); // 2
🧩 옵셔널 체이닝(optional chaining) 연산자: ?.
→ 좌항의 피연산자가 null 또는 undefined인 경우 undefined를 반환하고 그렇지 않으면 우항의 프로퍼티 참조를 이어간다
// elem이 null 또는 undefined이면 undefined를 반환, 그렇지 않으면 우항의 프로퍼티 참조를 이어간다
let elem = null;
let value = elem?.value;
console.log(value); // undefined
// elem이 Falsy 값이면 elem으로 평가되고 elem이 Truthy 값이면 elem.value로 평가된다
let elem = null;
let value = elem && elem.value;
console.log(value); // undefined
→ 논리 연산자 &&는 좌항 피연산자가 Falsy 값(false, undefined, null, 0, -0, NaN, ‘’)이면 좌항의 피연산자를 그대로 반환한다
→ 좌항 피연산자가 Falsy값인 0이나 ‘’인 경우도 마찬가지지만 0이나 ‘’은 객체로 평가될 수 있다
let str = '';
// 문자열의 길이를 참조한다
let length = str && str.length;
// 문자열의 길이를 참조하지 못한다
console.log(length); // ''
→ 옵셔널 체이닝 연산자는 좌항 피연산자가 falsy 값이라도 null이나 undefined가 아니면 우항의 프로퍼티 참조를 이어간다
let str = '';
let length = str?.length;
console.log(length); // 0
🧩 null 병합 연산자(nullish coalescing): ??
→ 좌항의 피연산자가 null 또는 undefined인 경우 우항의 피연산자를 반환하고 그렇지 않으면 좌항의 피연산자를 반환한다
→ 변수에 기본값을 설정할 때 유용하다
let foo = null ?? 'default string';
console.log(foo); // "default string"
// Falsy 값인 0이나 ''도 기본값으로서 유효하다면 예기치 않은 동작이 발생할 수 있다
let foo = '' || 'default string';
console.log(foo); // "default string"
// 좌항의 피연산자가 Falsy 값이라도 null 또는 undefined가 아니면 좌항의 피연산자를 반환한다
let foo = '' ?? 'default string';
console.log(foo); // ""
'HTML+CSS+JavaScript > DeepDive' 카테고리의 다른 글
코어 자바스크립트2: nullish 병합 연산자 (0) | 2022.08.11 |
---|---|
코어 자바스크립트1: 논리 연산자 (0) | 2022.08.09 |
8장 제어문: 코어 자바스크립트3 (0) | 2022.08.02 |
8장 제어문: 코어 자바스크립트2 (0) | 2022.08.02 |
8장 제어문: 코어 자바스크립트1 (0) | 2022.08.02 |