diff --git "a/week1/ECMAScript\354\231\200-JavaScript\354\235\230-\354\227\260\352\264\200\354\204\261.md" "b/week1/ECMAScript\354\231\200-JavaScript\354\235\230-\354\227\260\352\264\200\354\204\261.md" index 44a3279..820eadf 100644 --- "a/week1/ECMAScript\354\231\200-JavaScript\354\235\230-\354\227\260\352\264\200\354\204\261.md" +++ "b/week1/ECMAScript\354\231\200-JavaScript\354\235\230-\354\227\260\352\264\200\354\204\261.md" @@ -1,7 +1,9 @@ # ECMAScript와 JavaScript의 연관성 > **Create Date**: 2022/12/09 -> [노션에서 확인하기](https://areumsheep.notion.site/ECMAScript-JavaScript-4d15fef29a9c4b658b5e5691528f2cf7) +> **Update Date**: 2023/01/01 +> +> [노션에서 확인하기](https://areumsheep.notion.site/ECMAScript-JavaScript-a8caaaa4f32444408d67eaf3346b4efa) ES6, ES2016, ES2021 등등 ES가 들어가는 말들을 보신 적이 있을 겁니다. 혹시 ES6가 무엇인지 설명할 수 있으신 분이 계실까요? diff --git "a/week1/JavaScript\354\235\230-\354\227\255\354\202\254.md" "b/week1/JavaScript\354\235\230-\354\227\255\354\202\254.md" index 3d774a7..406db65 100644 --- "a/week1/JavaScript\354\235\230-\354\227\255\354\202\254.md" +++ "b/week1/JavaScript\354\235\230-\354\227\255\354\202\254.md" @@ -1,11 +1,11 @@ # JavaScript의 역사 > **Create Date**: 2022/11/29 -> **Update Date**: 2022/12/06 +> **Update Date**: 2023/01/01 > > [JavaScript: the first 20 year](https://dl.acm.org/doi/pdf/10.1145/3386327)를 참고하여 작성되었으나, 오역이 있을 수 있습니다. > -> [노션에서 확인하기](https://areumsheep.notion.site/JavaScript-91d8d800280741249226c44ffd0e768b) +> [노션에서 확인하기](https://areumsheep.notion.site/JavaScript-5218abe7507848e0879d1db49c272512) ![**참고**: [https://buggyprogrammer.com/difference-between-java-and-javascript/](https://buggyprogrammer.com/difference-between-java-and-javascript/)](images/JavaScript의-역사/thumbnail.png) diff --git a/week1/var-let-const.md b/week1/var-let-const.md index c5837c0..b219e4e 100644 --- a/week1/var-let-const.md +++ b/week1/var-let-const.md @@ -1,7 +1,9 @@ # var / let / const > **Create Date**: 2022/12/09 -> [노션에서 확인하기](https://areumsheep.notion.site/var-let-const-685a665d15e74ed0a65558d56c76230d) +> **Update Date**: 2023/01/01 +> +> [노션에서 확인하기](https://areumsheep.notion.site/var-let-const-321ed794561c4b20a7dd4577ae591422) 자바스크립트에는 타입이 없습니다. 그럼 변수 선언을 어떻게 해야할까요? diff --git "a/week1/\353\266\204\355\225\264\355\225\240\353\213\271.md" "b/week1/\353\266\204\355\225\264\355\225\240\353\213\271.md" index 8d7bddd..3c06499 100644 --- "a/week1/\353\266\204\355\225\264\355\225\240\353\213\271.md" +++ "b/week1/\353\266\204\355\225\264\355\225\240\353\213\271.md" @@ -1,7 +1,9 @@ # 분해할당 > **Create Date**: 2022/12/09 -> [노션에서 확인하기](https://areumsheep.notion.site/78ee025858744e4f9d80fcda38f0c061) +> **Update Date**: 2023/01/01 +> +> [노션에서 확인하기](https://areumsheep.notion.site/3787a36b38f840bdadb73f2ed27eda71) ES6에서 선언과 할당을 합친 일종의 복합 문법을 도입했습니다. diff --git "a/week2/\355\203\200\354\236\205.md" "b/week2/\355\203\200\354\236\205.md" index 1208aa6..c2f02eb 100644 --- "a/week2/\355\203\200\354\236\205.md" +++ "b/week2/\355\203\200\354\236\205.md" @@ -3,7 +3,7 @@ > **Create Date**: 2022/12/14 > **Update Date**: 2022/12/16 > -> [노션에서 확인하기](https://areumsheep.notion.site/a0b7d622868d434785904b43a7c3c810) +> [노션에서 확인하기](https://areumsheep.notion.site/74930a7a2046429ab0859a3d6984df26) 프로그래밍 언어에서 어떤 타입을 지원하는지가 프로그래밍 언어의 가장 기본적인 특징이 됩니다. 자바스크립트의 변수 타입은 크게 원시 타입과 참조 타입이 있습니다. diff --git "a/week2/\355\221\234\355\230\204\354\213\235-\353\254\270-\354\227\260\354\202\260\354\236\220.md" "b/week2/\355\221\234\355\230\204\354\213\235-\353\254\270-\354\227\260\354\202\260\354\236\220.md" index 952f9e1..a51f254 100644 --- "a/week2/\355\221\234\355\230\204\354\213\235-\353\254\270-\354\227\260\354\202\260\354\236\220.md" +++ "b/week2/\355\221\234\355\230\204\354\213\235-\353\254\270-\354\227\260\354\202\260\354\236\220.md" @@ -3,7 +3,7 @@ > **Create Date**: 2022/12/14 > **Update Date**: > -> [노션에서 확인하기](https://areumsheep.notion.site/6509d9d9637d4b29ae660d1a1ce5efd8) +> [노션에서 확인하기](https://areumsheep.notion.site/da45abc3d8be43a0a146e6ed8bef13d9) 자바스크립트의 표현식, 연산자, 문에 대해 모든 걸 다 이야기하면 24시간도 부족할 정도로 많습니다. 여러 분도 알게 모르게 사용하고 계시겠죠! diff --git "a/week2/\355\230\270\354\235\264\354\212\244\355\214\205-TDZ.md" "b/week2/\355\230\270\354\235\264\354\212\244\355\214\205-TDZ.md" index 4ec3b80..de57383 100644 --- "a/week2/\355\230\270\354\235\264\354\212\244\355\214\205-TDZ.md" +++ "b/week2/\355\230\270\354\235\264\354\212\244\355\214\205-TDZ.md" @@ -3,7 +3,7 @@ > **Create Date**: 2022/12/09 > **Update Date**: 2022/12/13 > -> [노션에서 확인하기](https://areumsheep.notion.site/TDZ-d41b33b78f9d4081b27462fa68e36d78) +> [노션에서 확인하기](https://areumsheep.notion.site/TDZ-49306ff786c448e9aa66e7539ee2be3c) 호이스팅은 무엇일까요? **변수 선언을 최상단으로 올리는 것입니다.** 라고 하기엔 설명이 부족해보입니다. diff --git "a/week3/\353\260\260\354\227\264-\353\271\204\354\212\267\355\225\234-\352\260\235\354\262\264.md" "b/week3/\353\260\260\354\227\264-\353\271\204\354\212\267\355\225\234-\352\260\235\354\262\264.md" index 0d11e3f..85afe4e 100644 --- "a/week3/\353\260\260\354\227\264-\353\271\204\354\212\267\355\225\234-\352\260\235\354\262\264.md" +++ "b/week3/\353\260\260\354\227\264-\353\271\204\354\212\267\355\225\234-\352\260\235\354\262\264.md" @@ -3,7 +3,7 @@ > **Create Date**: 2022/12/21 > **Update Date**: 2022/12/21 > -> [노션에서 확인하기](https://areumsheep.notion.site/331542f240fa46c1b111f2e7f8fc929c) +> [노션에서 확인하기](https://areumsheep.notion.site/e7a1dea647e94b7984a81324fd249d49) 자바스크립트에는 배열과 비슷한 객체가 존재합니다. 영어로는 array-like object라고 합니다. diff --git "a/week3/\353\260\260\354\227\264-\354\204\261\352\270\264-\353\260\260\354\227\264.md" "b/week3/\353\260\260\354\227\264-\354\204\261\352\270\264-\353\260\260\354\227\264.md" index d2d6526..d28d62f 100644 --- "a/week3/\353\260\260\354\227\264-\354\204\261\352\270\264-\353\260\260\354\227\264.md" +++ "b/week3/\353\260\260\354\227\264-\354\204\261\352\270\264-\353\260\260\354\227\264.md" @@ -3,7 +3,7 @@ > **Create Date**: 2022/12/21 > **Update Date**: 2022/12/22 > -> [노션에서 확인하기](https://areumsheep.notion.site/5e4b76a797c6495186f38865a2aeec30) +> [노션에서 확인하기](https://areumsheep.notion.site/f104600971c9488c8e50229fbeda0a05) 여러분들은 배열에 대해 잘 알고 계실겁니다. 하지만 조금 더 세세하게 알아보는 계기가 되었으면 하여 준비한 자료입니다! diff --git "a/week3/\355\203\200\354\236\205-\353\263\200\355\231\230.md" "b/week3/\355\203\200\354\236\205-\353\263\200\355\231\230.md" index 865e769..a173efe 100644 --- "a/week3/\355\203\200\354\236\205-\353\263\200\355\231\230.md" +++ "b/week3/\355\203\200\354\236\205-\353\263\200\355\231\230.md" @@ -3,7 +3,7 @@ > **Create Date**: 2022/12/19 > **Update Date**: 2022/12/21 > -> [노션에서 확인하기](https://areumsheep.notion.site/f7d5b3bcdf0a4d0d8c28a14fab9b74e0) +> [노션에서 확인하기](https://areumsheep.notion.site/67c0520aa49f4ac1bee2ddba581e1e13) 지난 시간 자바스크립트에는 크게 원시 타입과 참조 타입이 있다고 말씀드렸습니다. 타입을 변경하는 방법에는 **명시적 타입 변환, 암묵적 타입 변환** 총 2가지가 있습니다. diff --git a/week4/QUIZ.md b/week4/QUIZ.md new file mode 100644 index 0000000..356dc8b --- /dev/null +++ b/week4/QUIZ.md @@ -0,0 +1,106 @@ +## 📝 4주차 퀴즈 + +### 빈 칸 채우기 + +ex) 스터디 리더는 (양아름) 입니다. + +1. 객체를 생성하게 되면 자신만의 프로퍼티를 가지는 것 외 ()라고 불리는 다른 객체에서 프로퍼티를 상속하기도 한다. +2. 선언 당시의 환경(스코프)에 대한 정보를 담은 객체를 ()라고 한다. +3. 한 번 정의하면 몇 번이고 호출할 수 있는 자바스크립트 코드 블록을 ()이라 한다. +4. 자신이 생성될 때의 환경(스코프)를 기억하는 함수를 ()라고 한다. +5. 함수 안에 함수를 적용하는 방식을 ()라고 한다. +6. 화살표 함수는 자신이 정의된 환경의 ()키워드 값을 상속한다는 특징을 가지고 있다. +7. 이전에 계산된 결과를 캐시하여 동일한 상황에 같은 계산을 반복하지 않고 이전 값을 사용하는 것을 ()이라 한다. +8. new Date()를 선언하면 Date.prototype, Object.prototype 순으로 연결되어 있는데 이것처럼 프로토타입 객체 사이의 연결을 ()이라 한다. + +### O / X 퀴즈 (만약 X라면 이유도 작성하면 좋아요!) + +ex) 스터디는 매주 목요일마다 진행됩니다. +X, 매주 금요일마다 진행됩니다. + +1. 화살표 함수는 함수 선언문이다. + **답**: + +2. 자바스크립트의 일부 함수만 클로저이다. + **답**: + +3. 프로토타입 객체와 `__proto__`는 같은 단어이다. + **답**: + +4. constructor와 `__proto__`는 같은 단어이다. + **답**: + +5. 클로저를 사용하면 변수를 비공개 상태로 사용할 수 있는데 함수 호출 시점의 로컬 변수를 캡처하기 때문이다. + **답**: + +### 코드 퀴즈 + +1. 객체를 생성하는 3가지 방법을 모두 이용해 간단히 코드로 구현해보세요! + +```javascript +// 1) 객체 리터럴 + +// 2) new + +// 3) Object.create() +``` + +2. subject 변수를 매개변수로 받은 math, english 값으로 변경하려 합니다. 주석으로 표현한 빈칸을 직접 채워보세요! + +```javascript +let subject = { + math: 80, + english: 90, +}; + +const setSubject = (math, english) => { + // 여기에는 어떤 코드가 들어갈까요? + // 힌트: 객체에서 다룬 TMI를 확인해보세요! +}; + +setSubject(40, 99); +``` + +3. 아래 코드에서 출력될 답안을 작성해보세요! + +```javascript +const today = new Date(); +console.log(today.__proto__); //답: +console.log(today.constructor); //답: + +const copy = today; +console.log(typeof copy); //답: + +console.log(copy.prototype === Date().prototype); //답: +``` + +4. 클로저를 이용하여 private method를 만드려 합니다. 주석으로 표현한 빈칸을 채워보세요! + +```javascript +function counter() { + let privateTarget = 0; + const changeBy = (value) => { + privateTarget += value; + }; + + return { + increment: function () { + // 여기에는 어떤 코드가 들어갈까요? + }, + decrement: function () { + // 여기에는 어떤 코드가 들어갈까요? + }, + value: function () { + return privateTarget; + }, + }; +} + +const countTest = counter(); +console.log(countTest.value()); // => 0 +countTest.increment(); +countTest.increment(); +console.log(countTest.value()); // => 2 +countTest.decrement(); +console.log(countTest.value()); // => 1 +``` diff --git a/week4/README.md b/week4/README.md new file mode 100644 index 0000000..a991dfc --- /dev/null +++ b/week4/README.md @@ -0,0 +1,11 @@ +## 🔍 4주차 발표자료 + +- [객체](객체.md) +- [프로토타입](프로토타입.md) +- [함수-화살표-함수](함수-화살표-함수.md) +- [클로저-중첩-함수](클로저-중첩-함수.md) +- [메모이제이션](메모이제이션.md) + +## 🤨 4주차 퀴즈 + +- [퀴즈 확인하기](QUIZ.md) diff --git "a/week4/images/\355\201\264\353\241\234\354\240\200-\354\244\221\354\262\251-\355\225\250\354\210\230/Untitled.png" "b/week4/images/\355\201\264\353\241\234\354\240\200-\354\244\221\354\262\251-\355\225\250\354\210\230/Untitled.png" new file mode 100644 index 0000000..27d5605 Binary files /dev/null and "b/week4/images/\355\201\264\353\241\234\354\240\200-\354\244\221\354\262\251-\355\225\250\354\210\230/Untitled.png" differ diff --git "a/week4/images/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/Untitled 1.png" "b/week4/images/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/Untitled 1.png" new file mode 100644 index 0000000..368e898 Binary files /dev/null and "b/week4/images/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/Untitled 1.png" differ diff --git "a/week4/images/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/Untitled 2.png" "b/week4/images/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/Untitled 2.png" new file mode 100644 index 0000000..51fbda8 Binary files /dev/null and "b/week4/images/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/Untitled 2.png" differ diff --git "a/week4/images/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/Untitled 3.png" "b/week4/images/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/Untitled 3.png" new file mode 100644 index 0000000..6b4daa5 Binary files /dev/null and "b/week4/images/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/Untitled 3.png" differ diff --git "a/week4/images/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/Untitled 4.png" "b/week4/images/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/Untitled 4.png" new file mode 100644 index 0000000..26708f6 Binary files /dev/null and "b/week4/images/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/Untitled 4.png" differ diff --git "a/week4/images/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/Untitled.png" "b/week4/images/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/Untitled.png" new file mode 100644 index 0000000..0d3e75c Binary files /dev/null and "b/week4/images/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205/Untitled.png" differ diff --git "a/week4/\352\260\235\354\262\264.md" "b/week4/\352\260\235\354\262\264.md" new file mode 100644 index 0000000..884f9e6 --- /dev/null +++ "b/week4/\352\260\235\354\262\264.md" @@ -0,0 +1,123 @@ +# 객체 + +> **Create Date**: 2022/12/30 +> **Update Date**: 2022/12/30 +> +> [노션에서 확인하기](https://areumsheep.notion.site/451436da78114c6eb01c9c53ed5c6efa) + +객체는 자바스크립트의 가장 기본적인 데이터 타입이며 저희는 이미 살펴본 적이 있습니다. +객체는 자바스크립트에서 굉장히 중요한 부분이므로 객체가 어떻게 동작하는지 자세히 이해해봅시다! + +## 객체란? + +객체는 복합된 값입니다. +객체는 여러 가지 값(기본 값이나 다른 객체)을 모아서 이름을 통해 값을 저장하고 가져올 수 있게 합니다. + +```jsx +const obj = { + hello: 'world', + name: 'secret', +}; + +obj.map; +``` + +객체는 단순히 문자열과 값만 연결한 것이 아닙니다. 자바스크립트 객체는 자신만의 프로퍼티를 가지는 것 외에도 **프로토타입**이라고 불리는 다른 객체에서 프로퍼티를 상속하기도 합니다. + +이 **프로토타입 상속**이 자바스크립트의 중요한 기능입니다. + +## 객체 생성 + +### 객체 리터럴 + +위에 예시를 들었던 코드가 바로 객체 리터럴을 사용하여 객체를 생성한 코드입니다. +다시 한 번 가져올까요? + +```jsx +const obj = { + hello: 'world', + name: 'secret', + test: 'test', +}; +``` + +콜론으로 구분한 `이름: 값` 형식으로 되어져 있는 것을 확인할 수 있습니다. + +객체 리터럴의 마지막 프로퍼티 뒤에 콤마를 쓸 수 있습니다. 이렇게 마지막에 콤마를 남겨둔다면 객체의 프로퍼티를 추가할 때 문법 에러를 초래할 가능성이 줄어들기에 이런 스타일을 권장하는 사람도 있습니다. + +### new + +```jsx +const o = new Object(); +const a = new Array(); +``` + +new 연산자는 새 객체를 생성하고 초기화합니다. new 키워드 뒤에는 반드시 함수 호출이 있어야 합니다. +이런 형태로 사용하는 함수를 **생성자**라고 부르고 **새로 생성된 객체를 초기화하는 목적**으로 사용합니다. + +### Object.create() + +> 해당 부분을 읽기 전에 [프로토타입](프로토타입.md)을 먼저 읽고 오시는 것을 추천합니다!! + +첫 번째 인자를 프로토타입 삼아 새 객체를 생성하는 방법입니다. +임의의 프로토타입을 사용하여 새 객체를 만들 수 있는 것은 **강력한 기능**입니다. + +```jsx +const o = Object.create({ x: 1, y: 2 }); // => Object.prototype +const a = Object.create(Array.prototype); // => Array.prototype / Object.prototype + +const d = Object.create(Date.prototype); // ?? +``` + +- **d에는 어떤 프로토타입이 있을까요?** + Date.prototype / Object.prototype + +## TMI + +### 단축 프로퍼티 + +ES6 이후에는 같은 변수명 일 시 콜론을 생략한 훨씬 간결한 문법을 사용할 수 있습니다. + +```jsx +let x = 1, + y = 2; +const o = { + x: x, + y: y, +}; + +//위의 코드는 아래와 같이 수정이 가능합니다. +const o = { + x, + y, +}; +``` + +### 분해 연산자 + +**ES2018** 이후에는 객체 리터럴 안에서 분해 연산자 …를 사용해 기존 객체의 프로퍼티를 새 객체에 복사할 수 있습니다. + +```jsx +const position = { x: 0, y: 0 }; +const dimensions = { width: 100, height: 75 }; + +const rect = {...position, ...dimensions }; + +for(n) { + const rect = {...position, ...dimensions }; // 2 * 2 * n +} +``` + +저희에겐 그저 점 3개일 수 있겠지만 자바스크립트 인터프리터가 상당히 많은 일을 하게 될 수도 있습니다. + +객체에 프로퍼티가 n개 있다면 이 프로퍼티를 다른 객체로 분해하는 작업은 $O(n)$ 작업일 겁니다. + +…를 루프나 재귀 함수에 넣어 데이터를 큰 객체 하나에 누산한다면 어떻게 될까요? +$n$이 커질수록 비효율적인 $O(p^2)$ 알고리즘을 쓰게 됩니다. + +## 참고 자료 + +- 자바스크립트 완벽가이드 +- [https://evan-moon.github.io/2019/10/23/js-prototype](https://evan-moon.github.io/2019/10/23/js-prototype) +- [https://ko.javascript.info/native-prototypes](https://ko.javascript.info/native-prototypes) +- [https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/create](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/create) diff --git "a/week4/\353\251\224\353\252\250\354\235\264\354\240\234\354\235\264\354\205\230.md" "b/week4/\353\251\224\353\252\250\354\235\264\354\240\234\354\235\264\354\205\230.md" new file mode 100644 index 0000000..2badcc4 --- /dev/null +++ "b/week4/\353\251\224\353\252\250\354\235\264\354\240\234\354\235\264\354\205\230.md" @@ -0,0 +1,40 @@ +# 메모이제이션 + +> **Create Date**: 2022/12/30 +> **Update Date**: 2022/12/30 +> +> [노션에서 확인하기](https://areumsheep.notion.site/eaa583eb2c6342bbb6f17daaf2c6fad6) + +메모이제이션(memoization) 아시는 분 계실까요? + +간단합니다! **이전에 계산한 결과를 캐시하여 동일한 상황에 같은 계산을 반복하지 않고 사용하는 것**을 메모이제이션이라 합니다. + +팩토리얼을 메모이제이션으로 구현해보겠습니다. + +```jsx +function factorial(n) { + if (Number.isInteger(n) && n > 0) { + if (!(n in factorial)) { + factorial[n] = n * factorial(n - 1); + } + return factorial[n]; + } else { + return '잘못된 숫자가 입력되었습니다.'; + } +} + +factorial[1] = 1; // 캐시를 초기화합니다. +factorial(6); // => 720 +factorial[5]; // => 120 / 이 값은 이미 캐시에 존재합니다. +``` + +이 부분을 간단히 다룬 이유는 리액트에 메모이제이션 훅이 있기 때문입니다. + +- `useMemo`는 메모이제이션된 값을 반환합니다. +- `useCallback`은 메모이제이션된 콜백을 반환합니다. + +## 참고 자료 + +- 자바스크립트 완벽가이드 +- [https://ko.reactjs.org/docs/hooks-reference.html#usecallback](https://ko.reactjs.org/docs/hooks-reference.html#usecallback) +- [https://ko.reactjs.org/docs/hooks-reference.html#usememo](https://ko.reactjs.org/docs/hooks-reference.html#usememo) diff --git "a/week4/\355\201\264\353\241\234\354\240\200-\354\244\221\354\262\251-\355\225\250\354\210\230.md" "b/week4/\355\201\264\353\241\234\354\240\200-\354\244\221\354\262\251-\355\225\250\354\210\230.md" new file mode 100644 index 0000000..d2c50d7 --- /dev/null +++ "b/week4/\355\201\264\353\241\234\354\240\200-\354\244\221\354\262\251-\355\225\250\354\210\230.md" @@ -0,0 +1,207 @@ +# 클로저 / 중첩 함수 + +> **Create Date**: 2022/12/30 +> **Update Date**: 2022/12/30 +> +> [노션에서 확인하기](https://areumsheep.notion.site/68467bcf20504849a7093da2e37afab6) + +저희는 이전에 스코프 4개를 배웠습니다. + +- **아시는 분….? 두 개씩 이야기해보아요 ㅎㅎ!** + - Global Scope, Script Scope, Function Local Scope, Block Scope + +저희는 클로저를 알기 위해 스코프를 하나 더 알아야 합니다. +바로 **어휘적 스코프**입니다! + +## 어휘적 스코프 (lexical scope) + +간단합니다! + +함수가 호출 시점의 스코프가 아니라 자신이 정의된 시점의 변수 스코프를 사용하여 실행된다는 뜻입니다. 기존 스코프들은 해당 변수를 사용할 수 있는 공간을 의미하는 scope였다면, 어휘적 스코프는 **선언된 공간**을 의미합니다. + +```jsx +const myName = 'Areum'; + +function getName() { + return myName; +} +``` + +위 예제 myName의 어휘적 스코프는 어디일까요? +myName은 전역 환경에서 선언되었기에 Global Scope(Script Scope)입니다. + +```java +function getName() { + const myName = "Areum"; + return myName; +} +``` + +- **위** myName**의 어휘적 스코프는 어디일까요?** + - getName()의 Local Scope 입니다. (Function Local Scope) + +```jsx +function showLastName() { + const lastName = 'Sofela'; + return lastName; +} + +function displayFullName() { + const fullName = 'Oluwatobi ' + lastName; + return fullName; +} + +console.log(displayFullName()); // => ReferenceError: lastName is not defined +``` + +위 코드를 자세히 보겠습니다. + +| | lastName | displayFullName | showLastName | +| ------------- | -------------------- | --------------- | ------------ | +| 어휘적 스코프 | showLastName의 Local | Global Scope | Global Scope | + +현재 displayFullName에서 lastName을 가져오고 있지만 어휘적 스코프를 본다면 각각 다른 공간에 있는 것을 확인하실 수 있습니다. + +이렇게 수정하면 어떨까요? + +```jsx +function showLastName() { + const lastName = 'Sofela'; + return lastName; +} + +function displayFullName() { + const fullName = 'Oluwatobi ' + showLastName(); + return fullName; +} + +console.log(displayFullName()); // => "Oluwatobi Sofela" +``` + +| | lastName | displayFullName | showLastName | +| ------------- | -------------------- | --------------- | ------------ | +| 어휘적 스코프 | showLastName의 Local | Global Scope | Global Scope | + +위 코드에서 같은 어휘적 스코프에 있는 showLastName을 이용하여 lastName을 출력할 수 있게 되었습니다! +저희는 이미 클로저를 사용하였습니다. + +클로저에 대해 더 자세히 알아봅시다!!!! + +## 클로저 + +> A **closure** is the combination of a function bundled together (enclosed) with references to its surrounding state (the **lexical environment**) +> +> **클로저는 함수와 그 함수가 선언됐을 때의 렉시컬 환경(Lexical environment)과의 조합이다.** +> 출처: [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures) + +말이 좀 어려운 것 같습니다. 코드와 함께 이해를 해보도록 하겠습니다. + +```jsx +let scope = 'global scope'; + +function checkScope() { + let scope = 'local scope'; + function f() { + return scope; + } + return f; +} + +console.log(checkScope()()); // 여기는 어떤 값이 출력될까요? +``` + +- **마지막 출력문에는 어떤 값이 출력될까요?** + - local scope + +왜 위의 답이 나오게 되었을까요? 자바스크립트 함수는 어휘적 스코프를 준수합니다. +그렇기에 자신이 정의된 스코프에 실행되게 되죠. + +그렇기에 f라는 함수는 **console.log에서 실행된 것처럼 보여도 실제로는 checkScope 함수 안에서 실행**이 된 것입니다. 간단히 말해 이것이 **클로저의 강력함**입니다. + +| | scope | checkScope | checkScope > scope | checkScope > f | +| ------------- | ------------ | ------------ | ------------------ | ------------------ | +| 어휘적 스코프 | Global Scope | Global Scope | checkScope의 local | checkScope의 local | + +위 mdn에서 다룬 말을 다시 정의해보자면 아래와 같습니다. + +> ⛰️ 클로저는 반환된 내부함수가 자신이 선언됐을 때의 환경인 스코프를 기억하여 자신이 선언됐을 때의 환경(스코프) 밖에서 호출되어도 그 환경(스코프)에 접근할 수 있는 함수 +> +> 즉, **클로저는 자신이 생성될 때의 환경(Lexical environment)을 기억하는 함수** 입니다. + +엄밀히 말해 **자바스크립트 함수는 모두 클로저**입니다. + +하지만 대부분의 함수가 자신이 정의된 곳과 같은 스코프에서 호출되므로 보통은 클로저인지 아닌지를 따질 필요가 없습니다. + +클로저를 사용하면 함수 호출 시점의 로컬 변수를 캡처하므로 **이 변수를 비공개 상태로 사용**할 수 있습니다. + +```jsx +function counter() { + let n = 0; + return { + log: function () { + console.log(n); + }, + count: function () { + return n++; + }, + reset: function () { + n = 0; + }, + }; +} + +const a = counter(); +a.count(); +a.reset(); +a.log(); + +a.n; // => undefined +``` + +counter안의 n에 접근하는 방법은 return에 정의된 함수로만 임시로 접근할 수 있습니다. + +### 중첩 함수 (Nested Funtion) = 내부 함수 (Inner Function) + +```jsx +let scope = 'global scope'; +function checkScope() { + let scope = 'local scope'; + function f() { + return scope; + } + return f; +} + +console.log(checkScope()()); // 여기는 어떤 값이 출력될까요? +``` + +저희가 위에서 다뤘던 **함수 안에 함수를 적용하는 방식**을 중첩 함수 혹은 내부 함수라고 부릅니다. + +## TMI) 스코프 체인 + +```jsx +var a = 'global'; + +function outer() { + var b = 'outer'; + + function inner() { + var c = 'inner'; + } +} +``` + +![참고: [https://www.youtube.com/watch?v=PVYjfrgZhtU](https://www.youtube.com/watch?v=PVYjfrgZhtU)](images/클로저-중첩-함수/Untitled.png) + +참고: [https://www.youtube.com/watch?v=PVYjfrgZhtU](https://www.youtube.com/watch?v=PVYjfrgZhtU) + +위 코드는 사진처럼 스코프 체인의 형태로 저장됩니다. +스코프 체인이 바인딩한 객체가 바로 렉시컬 스코프의 실체입니다. + +## 참고 자료 + +- 자바스크립트 완벽가이드 +- [https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures) +- [https://www.freecodecamp.org/news/javascript-lexical-scope-tutorial/](https://www.freecodecamp.org/news/javascript-lexical-scope-tutorial/) +- [https://poiemaweb.com/js-closure](https://poiemaweb.com/js-closure) +- [https://www.youtube.com/watch?v=PVYjfrgZhtU](https://www.youtube.com/watch?v=PVYjfrgZhtU) diff --git "a/week4/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205.md" "b/week4/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205.md" new file mode 100644 index 0000000..97ecc7a --- /dev/null +++ "b/week4/\355\224\204\353\241\234\355\206\240\355\203\200\354\236\205.md" @@ -0,0 +1,136 @@ +# 프로토타입 + +> **Create Date**: 2022/12/30 +> **Update Date**: 2022/12/30 +> +> [노션에서 확인하기](https://areumsheep.notion.site/fe89df42a21d450b9e20ded5fb6b59cd) + +객체 생성하는 3번째 방법을 알기 전에 프로토타입에 대해 알아야 합니다. + +자바스크립트에서 클래스는 같은 프로토타입 객체에서 프로퍼티를 상속하는 객체 집합입니다. +따라서 프로토타입 객체가 클래스의 핵심 기능입니다. + +## 프로토타입이란? + +자바스크립트 객체 거의 대부분은 자신과 연결된 두 번째 객체를 갖습니다. +여기서 **두 번째 객체는 프로토타입**이라고 부르며, **첫 번째 객체는 프로토타입에서 프로퍼티를 상속**합니다. + +![**출처**: [https://ko.javascript.info/native-prototypes](https://ko.javascript.info/native-prototypes)](images/프로토타입/Untitled.png) + +**출처**: [https://ko.javascript.info/native-prototypes](https://ko.javascript.info/native-prototypes) + +객체 리터럴을 사용해 생성한 객체는 모두 같은 프로토타입 객체를 갖습니다. +new 키워드와 생성자를 사용해 만든 객체는 생성자 함수의 prototype 프로퍼티 값을 자신의 프로토타입으로 사용합니다. + +**new Array()로 생성한 객체는 Array.prototype**를 갖고, **new Date()로 생성한 객체는 Date.prototype**을 갖습니다. (Array로 선언했을 때 배열 메서드를 사용가능하고, Date로 선언했을 때 날짜 관련 메서드를 사용할 수 있다는 것을 떠올리면 쉽습니다!) + +여기에서 중요한 부분은 거의 모든 객체에 프로토타입이 있지만 **prototype 프로퍼티가 있는 객체는 비교적 적다**는 것 입니다. prototype 프로퍼티를 갖는 객체가 다른 객체의 프로토타입을 정의합니다. + +**Object.prototype / Array.prototype / Date.prototype** << prototype 프로퍼티가 있는 객체 + +Object.prototype은 프로토타입이 없는 드문 객체 중 하나입니다. 이 객체는 어떤 프로퍼티도 상속하지 않습니다. +**내장 생성자 대부분에 Object.prototype에서 상속하는 프로토타입이 있습니다**. + +## 프로토타입 용어 + +프로토타입 생성되는 방법은 **객체를 생성할 때 원본 객체를 복제하여 생성하는 방법**입니다. +아래 예제를 볼까요? + +```jsx +function User() {} + +const evan = new User(); + +console.log(evan); // => User { __proto__: Object } +console.log(typeof evan); // => object +``` + +evan이라는 변수에 함수인 User라는 값을 넣었습니다. +가장 마지막 줄의 console.log를 볼까요? function이 아니라 object가 되었습니다. + +여기에서 저희는 evan이란 변수에는 User 함수를 생성하여 넣어준 것이 아니라, 사실 **User 함수의 프로토타입 객체를 복제하여 넣어준 것**을 알 수 있습니다. + +```jsx +console.log(User.prototype); // => User { __proto__: Object } +``` + +그래서 저희는 이렇게 출력을 하면 문제없이 작동하는 것을 확인할 수 있습니다. +함수를 생성하면 무조건 그 함수의 **프로토타입 객체**도 함께 생성된다는 것이 키포인트입니다. + +![**출처**: [https://evan-moon.github.io/2019/10/23/js-prototype](https://evan-moon.github.io/2019/10/23/js-prototype)](images/프로토타입/Untitled%201.png) + +**출처**: [https://evan-moon.github.io/2019/10/23/js-prototype](https://evan-moon.github.io/2019/10/23/js-prototype) + +### 프로토타입 객체 + +프로토타입 객체는 **함수를 사용해서 새로운 객체를 생성할 때 원본 객체 역할을 해줄 객체**를 의미합니다. +위 그림에선 User Prototype입니다. + +### constructor + +위 그림에서 constructor, **proto**라는 이상한 단어가 나왔습니다. + +constructor의 뜻은 **생성자** 죠! +자바스크립트에서도 똑같습니다. prototype을 생성한 함수의 값을 담고 있습니다. + +위 그림 같은 경우에는 User Function을 갖고 있겠네요. +아래와 같이 정리할 수 있습니다. + +![**출처**: [https://evan-moon.github.io/2019/10/23/js-prototype](https://evan-moon.github.io/2019/10/23/js-prototype)](images/프로토타입/Untitled%202.png) + +**출처**: [https://evan-moon.github.io/2019/10/23/js-prototype](https://evan-moon.github.io/2019/10/23/js-prototype) + +```jsx +console.log(User.prototype.constructor === User); // => true +``` + +### **proto** (프로토타입 링크) + +생성된 객체가 **자신의 원본 객체에 접근할 수 있는 프로퍼티**가 바로 **`__proto__`** 프로퍼티입니다. + +함수를 통해 새롭게 생성된 객체는 원본 객체와의 연결을 가지고 있습니다. 이때 이 연결을 `프로토타입 링크(Prototype Link)`라고 합니다. + +즉 **`User`** 함수를 사용하여 생성한 객체는 **`User.prototype`** 객체를 복사하여 생성된 객체이기 때문에, +이 객체들은 원본인 **`User.prototype`** 객체를 자신의 **`__proto__`** 프로퍼티에 연결해두는 것입니다. + +```jsx +function User() {} +const evan = new User(); +console.log(evan.__proto__ === User.prototype); // => true +``` + +## 프로토타입 체인 + +Date.prototype은 Object.prototype에서 프로퍼티를 상속하므로 +new Date()로 생성한 Date객체는 Date.prototype과 Object.prototype 양쪽에서 프로퍼티를 상속합니다. + +이렇게 이어지는 **프로토타입 객체 사이의 연결을 프로토타입 체인**이라 합니다. + +![**출처**: [https://ko.javascript.info/native-prototypes](https://ko.javascript.info/native-prototypes)](images/프로토타입/Untitled%203.png) + +**출처**: [https://ko.javascript.info/native-prototypes](https://ko.javascript.info/native-prototypes) + +위의 사진에서 알 수 있듯이 Object.prototype의 위에는 null이 있습니다. + +Object.prototype에도 toString()이라는 메서드가 있고, Array.prototype에도 toString()이라는 메서드가 있다면 가까운 메서드를 사용하게 됩니다. + +![**출처**: [https://ko.javascript.info/native-prototypes](https://ko.javascript.info/native-prototypes)](images/프로토타입/Untitled%204.png) + +**출처**: [https://ko.javascript.info/native-prototypes](https://ko.javascript.info/native-prototypes) + +```jsx +const a = [1, 2, 3]; + +a.toString(); //Error +``` + +`console.dir([1,2,3]);` 을 사용하면 내장 객체의 상속관계를 확인하는데 도움됩니다. + +## 참고 자료 + +- 자바스크립트 완벽가이드 +- [https://evan-moon.github.io/2019/10/23/js-prototype](https://evan-moon.github.io/2019/10/23/js-prototype) +- [https://ko.javascript.info/native-prototypes](https://ko.javascript.info/native-prototypes) +- [http://insanehong.kr/post/javascript-prototype/](http://insanehong.kr/post/javascript-prototype/) +- [https://www.youtube.com/watch?v=wUgmzvExL_E](https://www.youtube.com/watch?v=wUgmzvExL_E) +- [https://poiemaweb.com/js-prototype](https://poiemaweb.com/js-prototype) diff --git "a/week4/\355\225\250\354\210\230-\355\231\224\354\202\264\355\221\234-\355\225\250\354\210\230.md" "b/week4/\355\225\250\354\210\230-\355\231\224\354\202\264\355\221\234-\355\225\250\354\210\230.md" new file mode 100644 index 0000000..9c567a1 --- /dev/null +++ "b/week4/\355\225\250\354\210\230-\355\231\224\354\202\264\355\221\234-\355\225\250\354\210\230.md" @@ -0,0 +1,102 @@ +# 함수 / 화살표 함수 + +> **Create Date**: 2022/12/30 +> **Update Date**: 2022/12/30 +> +> [노션에서 확인하기](https://areumsheep.notion.site/71601abbc6264d808f880e539d28b037) + +함수는 **한 번 정의하면 몇 번이고 호출할 수 있는 자바스크립트 코드 블록**입니다. + +## 매개변수와 인자 + +```jsx +function sum(a, b) { + return a + b; +} + +sum(2, 3); +``` + +- **위 코드에서 매개변수와 인자는 무엇일까요?** + - 매개변수: a, b / 인자: 2, 3 + +```jsx +const array = { + push: () => [].push('a'), // <= 객체의 ㅁㅁㅁ? +}; +``` + +- **위의 push라는 함수는 객체의 ㅁㅁㅁ라고 부릅니다. ㅁ안에 들어갈 단어는 무엇일까요?** + - 메서드 + +## 화살표 함수 + +```jsx +function 함수_선언문() { + return '함수 선언문'; +} +const 함수_표현식 = function () { + console.log('함수 표현식'); +}; +``` + +이전에 이런 문제를 냈었습니다. +화살표 함수는 **함수 표현식**입니다. + +**ES6**에서 `=>` 를 이용해 간결한 문법으로 함수를 정의할 수 있습니다. + +```jsx +const isGenius = () => true; +``` + +화살표 함수는 문법이 간결하므로 다른 함수에 전달할 때 이상적입니다. +Array.method나 Object.method를 사용할 때 좋습니다. + +```jsx +// ES5 +var selected = allJobs.filter(function (job) { + return job.isSelected(); +}); + +// ES6 +var selected = allJobs.filter((job) => job.isSelected()); +``` + +화살표 함수는 다른 방법으로 정의된 함수와 차이점이 존재합니다. +바로 **자신이 정의된 환경의 this 키워드 값을 상속**한다는 것입니다. + +```jsx +// ES5 +function Person() { + this.age = 0; // `this`를 자신의 인스턴스로 정의. + + setInterval(function growUp() { + // 비엄격 모드에서, growUp() 함수는 `this`를 전역 객체로 정의 + // 이는 Person() 생성자에 정의된 `this`와 다릅니다. + // 따라서 외부 age, 내부 age는 다른 Reference를 가지고 있습니다. + this.age++; // dynamic scope # this + console.log(this.age); // NaN + }, 1000); +} + +var p = new Person(); + +// ES6 +function Person() { + this.age = 0; + + setInterval(() => { + this.age++; // lexical scope # this + console.log(this.age); // 1, 2, 3, 4, ... + }, 1000); +} + +var p = new Person(); +``` + +## 참고 자료 + +- 자바스크립트 완벽가이드 +- [https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/Arrow_functions](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions/Arrow_functions) +- [https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/](https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/) +- [https://nesoy.github.io/articles/2019-04/Javascript-Arrow-function](https://nesoy.github.io/articles/2019-04/Javascript-Arrow-function)