일반적으로 외부 함수의 실행이 끝나면, 외부 함수가 소멸되어 내부 함수가 외부 함수의 변수에 접근할 수 없다.
하지만 외부 함수의 실행이 끝나고 외부 함수가 소멸된 이후에도 내부 함수가 외부 함수의 변수에 접근할 수 있는 구조 를 클로저라고 한다
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()); // => 124
HA시험에서 클로저 부분이 제일 어려웠다...
참고 자료 - 드림코딩 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); // Lee
1function 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}