const
, let
은 block level scope를 가진다.
만약, 함수 내에서 const, let이 쓰인 경우 호이스팅될 때 함수 내부에서 제일 위로 호이스팅된다. 즉, 함수 내부에서만 유효한 범위를 가진다.
하지만 var
는 block level scope를 따르지 않기 때문에 호이스팅 시 전역에서 위로 호이스팅 되버린다. 헷갈릴 수 있으니 아싸리 쓰지 말자! 더 명확한 const와 let을 사용하자.
if (true) {
var a = 1;
const b = 2;
}
console.log(a); // if블록 내에서 var 키워드로 변수를 선언 했기 때문에
// 전역에서 a를 호출해도 1이 뜬다. ❌ BAD ❌
console.log(b); // b는 if블록 안에서만 유효함으로, undefined이 뜬다. ✅ GOOD ✅
잊지 말자! object는 key-value pair 이다!
// 객체 선언 방법
const dog = {
name: "Yeti",
age: 1,
breed: "Maltese",
doSomething: () => {},
}
const name = "Yeti";
const age = 1;
// 변경 전
const dog = {
name: "Yeti",
age: 1,
breed: "Maltese",
doSomething: () => {},
}
//단축속성 : key - value가 일치하면 생략
const person = {
name,
age,
breed: "Maltese",
doSomething: () => {},
}
const obj1 = { value1: 10 };
const obj2 = obj1; // ❌ 얕은 복사
const obj3 = JSON.parse(JSON.stringify(obj1)) // ✅ 깊은 복사
// obj1을 문자열로 풀고, 다시 JSON으로 파싱해서 새롭게 주소 참조함
// (물론 JSON으로 복사하면 중첩객체는 복사 안되기 때문에
// iterator 활용하거나 재귀 사용해서 더 깊은 것까지 복사해야 함)
obj1.value1 += 1;
console.log(`obj1:`, obj1); // ✅ 11
// +1 더했기 때문에
console.log(`obj2:`, obj2); // ❌ 11
// obj2 마찬가지로 얕은 복사를 했기 때문에 같이 11이 되버린다.
console.log(`obj3:`, obj3); // ✅ 10
// 깊은 복사를 했기 때문에 상관이 없다.
${}
)// 일반 텍스트
`string text`
// 멀티라인 지원
`string text line 1
string text line 2`
// 플레이스 홀더를 이용한 표현식으로 js 값 넣을 수 있음
`string text ${expression} string text`
const dog = {
name: "Yeti",
age: 1,
}
// dog 객체 안에 있는 값들이 구조가 해제되어 각각 변수에 할당
const { name, age } = dog;
console.log(`🐶 ${name} 강아지는, ${age}살 이예요!`);
const dog = {
name: "Yeti",
age: 1,
}
// 함수의 입력값 또한 각각 구조가 해제되어 각각 변수에 할당
// 🌟 특히 이 패턴 많이 씀!
function hello({name, age}) {
console.log(`🐶 ${name} 강아지는, ${age}살 이예요!`);
}
hello(dog);
// 객체와 마찬가지로 배열도 구조분해 할당 이루어짐
const testArr = [1, 2, 3, 4, 5];
const [val1, val2, val3, val4, val5] = testArr;
console.log(val1); // 1
console.log(val2); // 2
console.log(val3); // 3
console.log(val4); // 4
console.log(val5); // 5
let [name] = ["Yeti", 1, "Maltese"];
console.log(name); // "Yeti"
let [, age] = ["Yeti", 1, "Maltese"];
console.log(age); // 1
let [name, age, breed] = ["Yeti", 1, "Maltese"];
console.log(name, age, breed); // ["Yeti", 1, "Maltese"
let [name, age, breed, color] = ["Yeti", 1, "Maltese"];
console.log(name, age, breed, color);
// "Yeti", 1, "Maltese", undefined ❌
// 정의되지 않은 값에 대해서는 undefined이 뜬다.
let [name, age, region, color = "white"] = ["Yeti", 1, "Maltese"];
console.log(name, age, breed, color);
// "Yeti", 1, "Maltese", "white"
// ...rest 전개연산자를 활용하여 지정하지 않은 나머지 변수를 모두 할당할 수 있다.
let [name, ...rest] = ["Yeti", 1, "Maltese"];
console.log(rest); // [ 1, "Maltese" ]
let names = ["Gooreum", "Doongi"];
let dogs = ["Yeti", ...names, ...names];
console.log(dogs); // [ "Yeti", "Gooreum", "Doongi", "Gooreum", "Doongi" ]
let yeti = {
name: "Yeti",
age: 1,
breed: "Maltese",
color: "white",
};
let gooreum = {
...yeti, // yeti 값들을 복사해 온 뒤, 바꿈
name: "Gooreum",
age: 5,
breed: "Pomeranian"
};
console.log(gooreum);
// { name: 'Gooreum', age: 5, breed: 'Pomeranian', color: 'white' }
// yeti에서 컬러 빼고 다 바뀜
// ✅ 화살표 함수: 리턴 값을 한 줄로 적는 경우 {}, return 모두 적지 않는다.
const mysum1 = (x, y) => x + y;
console<.log(mysum1(1, 2)); // 3
// ❌ 화살표 함수: 중괄호를 쓸 경우 return을 반드시 넣어줘야 한다.
const mysum2 = (x, y) => {x, y};
console.log(mysum2(1, 2)); // undefined
// ✅ 화살표 함수: 리턴 값을 한 줄로 적는 경우 {}, return 모두 적지 않는다.
// 객체를 리턴할 경우에는 () 괄호로 감싸주기
const mysum3 = (x, y) => ({x: x, y: y});
console.log(mysum3(1, 2)); // { x: 1, y: 2 }
// ✅ 화살표 함수
const mysum4 = (x, y) => {
return {x: x, y: y};
}
console.log(mysum4(1, 2)); // { x: 1, y: 2 }
// ✅ 익명 함수를 변수에 할당
const mysum5 = function(x, y) {
return {x: x, y: y};
};
console.log(mysum5(1, 2)); // { x: 1, y: 2 }
// ✅ 함수 선언식
function mysum6(x, y) {
return {x: x, y: y};
}
console.log(mysum6(1, 2)); // { x: 1, y: 2 }