개발자가 의도적으로 값의 타입을 변환 하는 것을 명시적 타입 전환 또는 타입 캐스팅이라 한다.
let x = 10;
// 명시적 타입 변환
// 숫자를 문자열로 타입 캐스팅한다.
let str = x.toString();
console.log(typeof str, str); // string 10
// x 변수의 값이 변경된 것은 아니다.
console.log(typeof x, x); // number 10
암묵적 타입 변환(강제 타입 변환) 이란? 개발자의 의도와는 상관없이 표현식을 평가하는 도중에 암묵적으로 타입이 자동 변환 되기도 한다.
let x = 10;
// 암묵적 타입 변환
// 문자열 연결 연산자는 숫자 타입 x의 값을 바탕으로 새로운 문자열을 생성한다.
let str = x + '';
console.log(typeof str, str); // string 10
// x 변수의 값이 변경된 것은 아니다.
console.log(typeof x, x); // number 10
👉 명시적 타입 변환은 타입을 변경하겠다는 개발자의 의지가 코드에 명백히 들어난다. 하지만
가독성 측면에서 암묵적 타입 변환이 더 좋을 수 있다.
ex) 명시적 타입 변환 : (10).to String() / 암묵적 타입 변환: 10 + ' '
자바스크립트 엔진은 문자열 연결 연산자 표현식을 평가하기 위해 문자열 연결 연산자의 피연산자 중 문자열 타입이 아닌 피연산자를 문자열 타입으로 암묵적 타입 함
`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]"
자바스크립트 엔진은 산술 연산자 표현식을 평가하기 위해 산술 연산자의 피연산자 중에서 숫자 타입이 아닌 피연산자를 숫자 타입으로 암묵적으로 타입 변환함
1 - "1"; // 0
1 * "10"; // 10
1 / "one"; // NaN
"1" > 0; // true
+"" + // 0
"0" + // 0
"1" + // 1
"string" + // NaN
true + // 1
false + // 0
null + // 0
undefined + // 0
[] + // 0
{} + // NaN
[1, 2] + // NaN
function () {}; // NaN
자바스크립트 엔진은 조건식의 평가 결과를 불리언 타입으로 암묵적 타입 변환
if ("") console.log("1");
if (true) console.log("2"); // "2"
if (0) console.log("3");
if ("str") console.log("4"); // " 4 "
if (null) console.log("5");
// 나머지들은 모두 동작 안함
👉 자바스크립트 엔진은 불리언 타입이 아닌 값을 Turthy값 (참으로 평가되는 값) 또는 Falsy값 (거짓으로 평가되는 값) 으로 구분함
생성자 함수(String, Number, boolean 등)을 new 연산자 없이 호출되는 방법과 빌트인 메서드 사용하는 방법 , 암묵적 타입 변환을 이용하는 방법이 있다.
문자열 타입으로 변환
- String 생성자 함수를
new
키워드 없이 사용Object.prototype.toString
메서드 호출- 문자열과
+
연산 진행
String(1); // "1"
String(NaN); // "NaN"
String(true); // "true"
(1).toString(); // "1"
[1, 2, 3].join(","); // "1,2,3"
1 + "2"; // "12"
+
를 단항 연산자로 사용*
연산 진행(이 때도, 형변환후 NaN 이 되는 경우는 NaN만 나옴)Number("1"); // ""
Number(true); // 1
Number(false); // 0
parseInt("1"); // 1
parseFloat("5.6"); // 5.6;
+"2"; // 2
+true; // 1
1 * ""; // 1
!
: 부정 논리 연산자를 2번 사용 (falsy --> false, truthy --> true)Boolean("x"); // true
Boolean("false"); // false
Boolean(""); // false
Boolean(undefined); // false
Boolean(null); // false
Boolean({}); // true
Boolean([]); // true
!!"x"; // true
!!1; // true
!!undefined; // false
!!null; // false
!!{}; // true
!![]; // true
논리 연산자 중 논리합(
||
) 과 논리곱(&&
)은 표현식의 형가 결과는 불리언이 아닐 수 있다. 논리합(||
) 과 논리곱(&&
)은 피연산자 중 어느 한쪽으로 평가된다.
//예제 1
"Dog" && "Cat"; // "Cat" -> 논리 연산의 결과를 결정하는 두 번째 피연산자를 그대로 반환
"Dog" || "Cat"; // "Dog" -> 논리 연산의 결과를 결정한 첫 번째 피연산자를 반환
//예제 2
// 사용자가 로그인 상태이면 환영 메시지를 출력
let loggedIn = true;
let username = '유저1';
loggedIn && console.log('환영합니다! ' + username); //환영합니다! 유저1
loggedIn = false;
loggedIn && console.log('환영합니다! ' + username); //아무것도 출력되지 않음
👉 단축 평가란 논리 연산의 결과를 결정하는 피연산자를 타입 변환하지 않고 그대로 변환 한다. 평가하는 도중에 평가 결과가 확정된 경우 나머지 평가 과정은 생략함
단축 평가 표현식 | 평가 결과 |
---|---|
true || anything | true |
false || anything | anything |
true && anything | anything |
false && anything | false |
let done = false;
let msg = "";
// 조건 = true
if (done) msg = "완료";
msg = done && "완료";
console.log(msg); // 완료
let done = false;
let msg = "";
// 조건 = flase
if (!done) msg = "미완료";
msg = done || "미완료";
console.log(msg); // 미완료
// if ...else문과 삼항연산자
let done = true;
let msg = "";
// if ...else
if (done) msg = "완료";
else msg = "미완료";
console.log(msg); // 완료
// 삼항연산자로 대체
msg = done ? "완료" : "미완료";
console.log(msg); // 완료
연산자 ?.는 좌항이 피연산자가 null 또는 undefined를 반환 그렇지 않으면 우항의 프로퍼티를 참조한다.
// 예제 1
let elem = null;
var value = elem?.value;
console.log(value); // undefined -> elem이 null또는 undefined이면 undefined 반환
let str = "";
// 문자열의 길이를 참조.
let length = str?.length;
console.log(length); // 0
// 예제 2
const user = {
profile: {
name: "유저1",
details: {
age: 30,
location: "서울시 강남구"
}
}
};
console.log(user.profile.details.age); // 출력: 30
console.log(user2.profile?.details?.age); // 출력: undefined
연산자 ??는 좌항의 피연산자가 null 또는 undeefined인 경우 우항의 피연산자를 반환 그렇지 않으면 좌항의 피연산자를 반환함
// 예제1
let foo = null || "default string";
console.log(foo); // "default string"
let foo = "" || "default string";
console.log(foo); // "default string"
let foo = "" ?? "default string";
console.log(foo); // ""
// 예제2
// 사용자의 위치 설정이 없으면 기본 위치를 제공
let userLocation = null;
console.log(userLocation ?? 'Unknown location'); // 출력: Unknown location
userLocation = 'Seoul';
console.log(userLocation ?? 'Unknown location'); // 출력: Seoul
// 사용자 입력이 0인 경우에도 0을 유효한 값으로 취급
const temperature = 0;
console.log(temperature ?? 25); // 출력: 0
❗Null 병합 연산자와 논리합 연산자 (||
) 차이
// 논리합 연산자
const display = (item) => {
const textLength = item.textLength || 50;
console.log(textLength) // 50 -> 0은 falsy한 값이 아니기때문에 50이 출력됨
// Null 병합 연산자
const itemsperPage = item.itemsperPage ?? 10;
console.log(itemsperPage) // 0 -> 0은 falsy한 값이 아니기때문에 0이 출력됨
};
const userItem = {
textLength: 0,
itemsperPage:0,
}