일반적으로 외부 함수의 실행이 끝나면, 외부 함수가 소멸되어 내부 함수가 외부 함수의 변수에 접근할 수 없다.
하지만 외부 함수의 실행이 끝나고 외부 함수가 소멸된 이후에도 내부 함수가 외부 함수의 변수에 접근할 수 있는 구조 를 클로저라고 한다
1var num = 1;2
3function foo() {4  var num = 2;5
6  function bar() {7    console.log(num);8  }9  return bar;10}11
12var baz = foo();13baz(); // => 2위 코드에서
외부 함수 foo()는 리턴되어 사라진 후, 내부 함수 bar()가 생성된다.
그러나 여전히 내부 함수가 외부함수의 지역 변수에 접근할 수 있다.
외부 함수가 사라지지 않고 내부 함수의 참조로 인해 값을 유지하게 되는 것
이것을 클로저라고 부른다.
위 코드에선 내부 함수인 bar()를 클로저 함수라고 부른다.
1function f(arg) {2  var n = function () {3    return arg;4  };5  arg++;6  return n;7}8
9var m = f(123);10console.log(m()); // => 124HA시험에서 클로저 부분이 제일 어려웠다...
참고 자료 - 드림코딩 by 엘리, 모던JS튜토리얼
1// 화살표 함수2arr.map((arg) => {...})3
4// 괄호 생략 가능5arr.map(arg => ...)1// 클래스2    class MyClass {3        constructor() {...}4        method() {...}5        ...6    }7
8    // 예제9    class User {10
11    constructor(name) {12        this.name = name;13    }14
15    sayHi() {16        alert(this.name);17    }18
19    }20
21    // 사용법:22    let user = new User("John");23    user.sayHi();예전에 정리했었는데 까먹었다...
1// 객체2  const student = {3    name: 'Anna',4    level: 1,5  };6
7  // 💩8    const name = student.name;9    const level = student.level;10    console.log(name, level); // => "Anna" 111
12  // ✨13    // 동일 이름으로 선언14    const { name, level } = student;15    console.log(name, level); // => "Anna" 116
17    // 새로운 이름으로 선언18    const { name: studentName, level: studentLevel } = student;19    console.log(studentName, studentLevel); // => "Anna" 120
21  // 배열22  const animals = ['🐶', '😽'];23
24  // 💩25  {26    const first = animals[0];27    const second = animals[1];28    console.log(first, second); // => 🐶 😽29  }30
31  // ✨32  {33    const [first, second] = animals;34    console.log(first, second); // => 🐶 😽35  }36}훔..
1// 이름과 성을 요소로 가진 배열2let arr = ["Bora", "Lee"];3
4// 구조 분해 할당을 이용해5// firstName엔 arr[0]을6// surname엔 arr[1]을 할당하였습니다.7let [firstName, surname] = arr;8
9alert(firstName); // Bora10alert(surname); // Lee1function func(userName = "홍길동") {2  console.log(userName);3}4
5func("김솔희"); // => "김솔희"6func(); // => "홍길동"1const isCat = true;2
3// 💩4{5  let component;6  if (isCat) {7    component = "😸";8  } else {9    component = "🐶";10  }11  console.log(component); // => 😸12}13
14// ✨15{16  const component = isCat ? "😸" : "🐶"; // isCat 이 true일 경우 고양이, 아니라면 강아지17  console.log(component); // => 😸18}1// 옵셔널 체이닝이 필요한 이유2let user = {}; // 주소 정보가 없는 사용자3
4alert(user.address.street.name); // TypeError: Cannot read property 'street' of undefined5
6// 똥 코드7alert(user && user.address && user.address.street && user.address.street.name); // undefined, 에러가 발생하지 않습니다.8
9// 똥 코드210alert(11  user.address12    ? user.address.street13      ? user.address.street.name14      : undefined15    : undefined16);17
18// 갓 코드19alert(user?.address?.street); // undefined, 에러가 발생하지 않습니다.1{2  const name = "Ellie";3  const userName = name || "Guest";4  console.log(userName);5}6
7{8  const name = null;9  const userName = name || "Guest";10  console.log(userName);11}12
13// 💩🐞🕷🦗🦟🐜 버그 덩어리14{15  const name = "";16  const userName = name || "Guest"; // 빈 문자열은 펄시한 값17  console.log(userName); // => Guest18
19  const num = 0;20  const message = num || "undefined"; // 0은 펄시21  console.log(message); // => undefined22}23
24// ✨25{26  const name = "";27  const userName = name ?? "Guest";28  console.log(userName); // => ""29
30  const num = 0;31  const message = num ?? "undefined";32  console.log(message); // => 033}