템플릿 리터럴에 대해 알아보자 기본 문자열은 "
, '
와 같은 따옴표로 시작해서 닫는 구조로 문자열을 표기하는 경우가 많다. 이런경우들은 꼭 같은 형태의 따옴표로 수미구조를 맞춰야 문자열로 인식하며 서로 +
기호로서 문자열을 합친다. 그 안에서의 개행은 /n
문자로 한다.
하지만 백틱
이라는 기호가 있다. 이 기호는 엄청나게 유용하게 사용할 수있다.
${}
(placeholder) 기호와 함께 말이다. 예제를 보자
const firstName = `Doo`;
const lastName = `Hyun`
const age = 17;
const doodream = `I'm ${firstName} ${lastName} and ${age}
Hello,
Nice to meet you`
console.log(doodream);
// I'm Doo Hyun and 17
// Hello,
// Nice to meet you
위와 같이 개행은 그냥 엔터를 쳐서 개행을 하면되고 문자열 중간에 ${}
기호를 넣어
변수를 데이터 타입상관없이 삽입가능하다. 심지어 여러번의 문자열 표기 '' , "" 없이 말이다.
따라서 문자열을 사용할 거다! 싶으면 무조건 백틱을 사용해도된다.
둘다 어떠한 변수의 데이터 타입의 유형을 변환한다. 하지만
Type conversion은 사용자가 완전히 수동적으로 사용하는 반면
Type coersion은 사용자 몰래 자동으로 혹은 암시적으로 이루어진다.
수동으로 형변환 하는 것이라고 생각하면 편하다.
//
const year = 1994;
const gender = `male`;
console.log(`I'm ` + String(year) + ` old`);
// 수동으로 문자열로 형변환을 시킨다. String(year)
console.log(Number(gender)); // NaN
// 수동으로 숫자로 형변환을 시킨다. Number(gender)
console.log(typeof NaN); // number
수동으로 형변환을 시켜 연산을 맞추었다.
NaN
은 숫자이긴 숫자인데 잘못된 숫자이다. 뭔가 표현할 수없는 잘못된 숫자라는 표현은 NaN
을 사용한다.
자바스크립트에서는 단항 연산자
와 산술 연산자
의 용법이 다릅니다.
//
const year = 1994;
console.log(`I'm ` + year + ` old`);//'I'm 1994 old'
console.log('24' + '3' + 3);//'2433' string
console.log('24' - '3' - 3);//18 number
console.log('3' ** '2'); // 9 number
console.log('3' - '2' + 5) // '1' + 5 = '15'
console.log('123' < 57); // false
console.log(5 + 6 + '4' + 9 - 4 - 2); // 1143
console.log(typeof +'5'); // number
자동으로 숫자인 변수가 문자열로 바뀌었다.
+
연산자에 대하여 문자열 +
숫자는 숫자가 문자열로 자동 형변환되어 출력한다.
-
연산자에 대하여 문자열 -
숫자는 문자열이 숫자로 자동 형변환되어 출력한다.
사실 대부분의 연산자에 대하여 문자열 연산자
에서 대부분은 문자열이 숫자로 변환된다. 특이한 것은 + 연산지 일때 뿐이다.!!
console.log(5 + 6 + '4' + 9 - 4 - 2); // 1143
console.log(typeof +'5'); // number
앞이 문자열이고 +
연산자가 있으면 뒷 피 연산자의 값이 문자열이든 숫자이든 값자체는 문자열로서 자동 형변환되어 계산되어진다.
하지만 앞이 숫자이거나 뒷 피 연산자의 값이 문자열이거나 숫자라면 값자체는 숫자로서 자동 형변환되어 계산되어진다.
당연히 이또한 연산자의 연산 순서와 연관되어 연산된다.
위 코드를 보면 알겠지만 언제 어떤 연산이 어떤 타입을 어떻게 변환시킬지 매우 까다롭게 알기 어렵다. 따라서 이러한 코드는 우리 코드에 매우 다양한 에러를 유발시킨다. 자동 형변환에 자주 의지하는 것은 악영향을 끼친다. 클린 코딩을 하려면 Type coerion을 피해야한다.
단순히 false와 true 이렇게 만 알고 있었지만 들여다보면 다양하게 보인다.
다양한 값들을 Boolean으로 형변환을 하면 true 혹은 false가 나온다.
이때 false가 되는 값들은 진짜 false 라는 속성을 갖고 있는 것이 아니라 그냥 true도 아닌 false도 아닌 속성을 갖게 되는 것이다.
// true
console.log(Boolean('a'));
console.log(Boolean(1));
console.log(Boolean(-1));
console.log(Boolean({}));
// false
console.log(Boolean(0));
console.log(Boolean(null));
console.log(Boolean(undefined));
console.log(Boolean(''));
이러한 형변환은 거의 coerion 형태로서 암시적으로 이루어지게된다.
그러면 어떤시점에서 이런 type coerion이 이뤄지게 될까?
const height;
if (height) { // 이 시점에서 height는 undefined 형태로 선언되어 있기때문에 자동으로 coerion 되어 false 값을 가지게 된다!
// if()의 괄호 안에서 javascript는 해당 값안에 있는 모든 값들을 Boolean 형태로 coerion한다.
console.log('Height is assigned!');
} else {
console.log('Height is not assigned!');
}
하지만 여기서도 버그가 발생하게된다.
const height = 0;
if (height) { // 0은 Boolean 형태로 변환 될때 false로 변환된다. 그런데 height는 정의되었는데 false로 넘어간다. 이는 사용자의 선택에 맞지 않을수 있다.
console.log('Height is assigned!');
} else {
console.log('Height is not assigned!');
}
height는 정의되었는데 false로 넘어간다. 이는 사용자의 선택에 맞지 않을수 있다. 이를 방지하기 위해서 평등연산자를 이용한 방법이있다.
const height = 0;
if (height === 0) {
console.log('Height is strict 0');
}
if( height == '0'){
console.log('Height is loose 0.. i dont know);
}
위코드를 보자면 === 연산자는 데이터 타입과 값을 동시에 비교해서 엄격하게 같은지 확인한다. 하지만 == 연산자는 coerion을 하면서 비교를 한다.
const height = 0;
if(height === '0') console.log("is it right?"); // 미출력
if(height == '0') console.log("loose 0");// 출력
이런 비교는 사용자가 원치 않는 경우가 많다. 이러한 규칙말고도 정말 다양한 규칙이 == 에 숨어있다. 클린 코딩을 지향하려면 ==
사용을 피해야한다. ==
라는 평등연산자가 없다고 생각해도 된다.
prompt 라는 전역객체에 정의된 함수가 있다.
const favorite = prompt("너가 가장 좋아하는 음식이뭐야?"); console.log(favorite);// 두릎 비빔밥 console.log(typeof favorite); // string
조건에 따라 실행할때 if else 구문을 많이 쓴다. 하지만 if else구문은 블럭블럭마다 변수가 정의되거나 해당변수를 조건 블럭 바깥에 정의해서 심지어 let으로 정의해서 해당 값을 재할당 하며 값을 줘야 한다.
const food = "rice"
let drink;
if(food === "rice"){
drink = "wine"
console.log(drink); // wine 출력
} else{
drink = "milk"
console.log(drink);
}
위코드는 굉장히 간단함에도 불구하고 변수를 재할당 했으며 중복된 코드가 보인다. 블럭이 간단한 한줄연산에 한에서 우리는 삼항연산자를 사용할수 있다.
const food = "rice"
const drink = food === "rice" ? "wine" : "milk";
drink는 조건부 연산으로 인해 재할당되지 않으므로 const 방식으로 변수설정을 하게되고 코드도 한줄로 끝난다.
연산 순서를 보자면
food === "rice" → true
wine
const drink = wine
이렇게 흘러가기 때문에 조건부 연산이 가능하다. 심지어 이과정을 템플릿 리터럴에서도 할수 있다.
const food = "rice"
console.log(`I wanna ${food === "rice" ? "wine" : "milk"}`) // I wanna wine;