├── INDEX.md ├── LICENSE ├── Level1 ├── [미션0] 계산기 │ ├── const.md │ ├── let.md │ ├── useful-array-method.md │ ├── useful-object-method.md │ └── var.md ├── [미션1] 자동차 경주 │ ├── class.md │ └── strict-mode.md └── [미션2] 로또 │ └── this.md ├── Level2 └── [미션0] 계산기 │ ├── first-class-object.md │ └── value-expression-statement.md └── README.md /INDEX.md: -------------------------------------------------------------------------------- 1 | # 레벨 1 2 | 3 | ## 미션 0 4 | * [var](https://github.com/nan-noo/js-dictionary/blob/main/Level1/%5B%EB%AF%B8%EC%85%980%5D%20%EA%B3%84%EC%82%B0%EA%B8%B0/var.md) 5 | * [let](https://github.com/nan-noo/js-dictionary/blob/main/Level1/%5B%EB%AF%B8%EC%85%980%5D%20%EA%B3%84%EC%82%B0%EA%B8%B0/let.md) 6 | * [const](https://github.com/nan-noo/js-dictionary/blob/main/Level1/%5B%EB%AF%B8%EC%85%980%5D%20%EA%B3%84%EC%82%B0%EA%B8%B0/const.md) 7 | * [유용한 배열 메서드](https://github.com/nan-noo/js-dictionary/blob/main/Level1/%5B%EB%AF%B8%EC%85%980%5D%20%EA%B3%84%EC%82%B0%EA%B8%B0/useful-array-method.md) 8 | * [유용한 객체 메서드](https://github.com/nan-noo/js-dictionary/blob/main/Level1/%5B%EB%AF%B8%EC%85%980%5D%20%EA%B3%84%EC%82%B0%EA%B8%B0/useful-object-method.md) 9 | 10 | ## 미션 1 11 | * [class](https://github.com/nan-noo/js-dictionary/blob/main/Level1/%5B%EB%AF%B8%EC%85%981%5D%20%EC%9E%90%EB%8F%99%EC%B0%A8%20%EA%B2%BD%EC%A3%BC/class.md) 12 | * [strict mode](https://github.com/nan-noo/js-dictionary/blob/main/Level1/%5B%EB%AF%B8%EC%85%981%5D%20%EC%9E%90%EB%8F%99%EC%B0%A8%20%EA%B2%BD%EC%A3%BC/strict-mode.md) 13 | 14 | ## 미션 2 15 | * [this](https://github.com/nan-noo/js-dictionary/blob/main/Level1/%5B%EB%AF%B8%EC%85%982%5D%20%EB%A1%9C%EB%98%90/this.md) 16 | 17 | # 레벨 2 18 | 19 | ## 미션 0 20 | * [값, 식, 문](https://github.com/nan-noo/js-dictionary/blob/main/Level2/%5B%EB%AF%B8%EC%85%980%5D%20%EA%B3%84%EC%82%B0%EA%B8%B0/value-expression-statement.md) 21 | * [일급객체](https://github.com/nan-noo/js-dictionary/blob/main/Level2/%5B%EB%AF%B8%EC%85%980%5D%20%EA%B3%84%EC%82%B0%EA%B8%B0/first-class-object.md) 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 TaeYoon 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Level1/[미션0] 계산기/const.md: -------------------------------------------------------------------------------- 1 | # const 2 | 3 | > 우테코 미션 할 때 되도록이면 const만 쓰자. let도 줄이자! 4 | 5 | ## 구문 및 정의 6 | 7 | ```js 8 | const varname1 = value1 [, varname2 = value2 [, ... [, varnameN = valueN]]]; 9 | ``` 10 | 11 | `varname` : 변수명, 식별자 12 | 13 | `value` : 변수 초기값 14 | 15 | --- 16 | 17 | ## 변수 선언 18 | 19 | - 데이터가 담길 메모리 공간 확보 20 | - 확보한 메모리 공간의 주소를 담음 21 | - 변수명(식별자)을 통해 해당 데이터에 접근할 수 있음 22 | 23 | ## 변수 선언을 해야 하는 이유 24 | 25 | ### 1. 선언하지 않은 변수는 항상 전역 변수 26 | 27 | ```js 28 | function x() { 29 | y = 1; 30 | var z = 2; 31 | } 32 | 33 | x(); 34 | 35 | console.log(y); // 1 36 | console.log(z); // ReferenceError: z is not defined 37 | ``` 38 | 39 | ### 2. 선언하지 않은 변수는 할당문이 실행되기 전까지 존재하지 않음 40 | 41 | ```js 42 | console.log(a); // ReferenceError: a is not defined 43 | console.log("still going..."); // 실행되지 않음 44 | 45 | var a; 46 | console.log(a); // undefined 47 | console.log("still going..."); // 실행됨 48 | ``` 49 | 50 | ### 3. 선언하지 않은 변수는 실행 컨텍스트 속성에서 변경 가능(configurable) 51 | 52 | ```js 53 | var a = 1; 54 | b = 2; 55 | 56 | delete this.a; // 실패 -> 선언된 변수는 non-configurable 57 | delete this.b; // 성공 -> b는 실행 컨텍스트(객체) 속성에서 제거됨 58 | 59 | console.log(a, b); // ReferenceError: b is not defined 60 | ``` 61 | 62 | ## 특징 63 | 64 | 기본적으로 let의 성질은 모두 갖고 있음 65 | 66 | ### 1. 선언과 초기화 67 | 68 | - 선언과 동시에 초기값을 할당해야 함 69 | 70 | ```js 71 | const x; // SyntaxError: Missing initializer in const declaration 72 | ``` 73 | 74 | ### 2. 재할당 금지 75 | 76 | ```js 77 | const x = 1; 78 | 79 | x = 100; // Uncaught TypeError: Assignment to constant variable 80 | ``` 81 | 82 | ### 3. 상수 선언 83 | 84 | - JS 상수 특징: 85 | - 대입 연산자로 재할당 불가능 86 | - 재선언 불가능 87 | - 초기값 필요 88 | - 같은 스코프 내에서 동일한 식별자 사용 불가 89 | - 상수로 할당된 객체의 속성은 보호되지 않음 90 | 91 | ```js 92 | const PI = 3.14; 93 | 94 | PI = 3.141592; // TypeError: 원시 값은 변경 불가능 95 | 96 | const NUMBER = { 97 | MAX: 9, 98 | MIN: 0, 99 | }; 100 | 101 | NUMBER.MIN = 1; // 객체 내부는 변경 가능 102 | 103 | NUMBER = 10; // TypeError: 새로운 객체 할당은 불가능 104 | ``` 105 | 106 | --- 107 | 108 | ## 참고 자료 109 | 110 | [**MDN: const**](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/const) 111 | 112 | **『코어 자바스크립트』** **_정재남 지음_** 113 | 114 | **『모던 자바스크립트 Deep Dive』** **_이웅모 지음_** 115 | 116 | --- 117 | 118 | ## 더 공부하기 119 | 120 | - var 121 | - let 122 | - data type 123 | - mutable, immutable 124 | -------------------------------------------------------------------------------- /Level1/[미션0] 계산기/let.md: -------------------------------------------------------------------------------- 1 | # let 2 | 3 | > 얘보단 const! 4 | 5 | ## 구문 및 정의 6 | 7 | ```js 8 | let varname1 [= value1] [, varname2 [= value2]] [, ..., varnameN [= valueN]]; 9 | ``` 10 | 11 | `varname` : 변수명, 식별자 12 | 13 | `value` : 변수 초기값 14 | 15 | --- 16 | 17 | ## 변수 선언 18 | 19 | - 데이터가 담길 메모리 공간 확보 20 | - 확보한 메모리 공간의 주소를 담음 21 | - 변수명(식별자)을 통해 해당 데이터에 접근할 수 있음 22 | 23 | ## 변수 선언을 해야 하는 이유 24 | 25 | ### 1. 선언하지 않은 변수는 항상 전역 변수 26 | 27 | ```js 28 | function x() { 29 | y = 1; 30 | var z = 2; 31 | } 32 | 33 | x(); 34 | 35 | console.log(y); // 1 36 | console.log(z); // ReferenceError: z is not defined 37 | ``` 38 | 39 | ### 2. 선언하지 않은 변수는 할당문이 실행되기 전까지 존재하지 않음 40 | 41 | ```js 42 | console.log(a); // ReferenceError: a is not defined 43 | console.log("still going..."); // 실행되지 않음 44 | 45 | var a; 46 | console.log(a); // undefined 47 | console.log("still going..."); // 실행됨 48 | ``` 49 | 50 | ### 3. 선언하지 않은 변수는 실행 컨텍스트 속성에서 변경 가능(configurable) 51 | 52 | ```js 53 | var a = 1; 54 | b = 2; 55 | 56 | delete this.a; // 실패 -> 선언된 변수는 non-configurable 57 | delete this.b; // 성공 -> b는 실행 컨텍스트(객체) 속성에서 제거됨 58 | 59 | console.log(a, b); // ReferenceError: b is not defined 60 | ``` 61 | 62 | ## 특징 63 | 64 | ### 1. 중복 선언 금지 65 | 66 | - 같은 스코프 내에서 중복 선언 금지 67 | 68 | ```js 69 | let x = 1; 70 | let x = 100; // Uncaught SyntaxError: Identifier 'x' has already been declared 71 | ``` 72 | 73 | ### 2. 블록 레벨 스코프 74 | 75 | - 자신을 선언한 블록을 로컬 스코프로 인정 76 | 77 | ```js 78 | let x = 1; 79 | 80 | // 블록으로 인해 새로운 스코프 생성 81 | if (true) { 82 | let x = 100; 83 | console.log(x); // 100 84 | } 85 | 86 | console.log(x); // 1 87 | ``` 88 | 89 | ### 3. TDZ(Temporal Dead Zone) 90 | 91 | - let으로 선언된 변수 스코프의 최상단에서 변수 초기화 완료 시점까지 92 | - 코드 작성 순서가 아닌, 코드 실행 순서에 의해 형성 93 | - 발생 이유 94 | - 코드가 실행되기 전, 자바스크립트 엔진은 이미 실행 환경의 변수명을 알고 있음(평가 과정) 95 | - let은 평가 과정에서, 선언 단계만 이뤄짐(초기값이 할당되지 않음) 96 | - 초기값 할당은 선언문이 실행될 때 이뤄짐 97 | 98 | ```js 99 | console.log(x); // Uncaught ReferenceError: x is not defined 100 | 101 | let x; // 초기값이 지정되어 있지 않으므로 undefined로 초기화 102 | 103 | console.log(x); // undefined 104 | 105 | x = 1; 106 | 107 | console.log(x); // 1 108 | ``` 109 | 110 | --- 111 | 112 | ## 예제 113 | 114 | ```js 115 | /* 전역에 let 선언 */ 116 | var x = "global"; 117 | let y = "global"; // 전역 객체에 속성을 추가하지 않음 118 | 119 | console.log(this.x); // "global" 120 | console.log(this.y); // undefined 121 | 122 | /* var와 let 같이 사용 */ 123 | let x = 1; 124 | var x = 2; // 재선언으로 인한 SyntaxError 125 | // 순서 반대로 선언해도 마찬가지(호이스팅) 126 | ``` 127 | 128 | --- 129 | 130 | ## 참고 자료 131 | 132 | [**MDN: let**](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/let) 133 | 134 | **『코어 자바스크립트』** **_정재남 지음_** 135 | 136 | **『모던 자바스크립트 Deep Dive』** **_이웅모 지음_** 137 | 138 | --- 139 | 140 | ## 더 공부하기 141 | 142 | - var 143 | - const 144 | - scope 145 | - execution context 146 | -------------------------------------------------------------------------------- /Level1/[미션0] 계산기/useful-array-method.md: -------------------------------------------------------------------------------- 1 | # 유용한 배열 메서드 2 | 3 | > 우테코 미션 할 때 for문 대신 아래 메서드들을 많이 활용하자! 반복문을 많이 사용하면, 오류 발생 가능성이 증가한다. 4 | 5 | ## 정적 메서드 6 | 7 | ### 1. Array.from() 8 | 9 | ```js 10 | Array.from(arrayLike[, mapFn[, thisArg]]) 11 | ``` 12 | 13 | `arrayLike` : 배열로 변환하고자 하는 유사 배열 객체나, 반복 가능한 객체 14 | 15 | `mapFn` : 배열의 모든 요소에 대해 호출할 맵핑 함수 16 | 17 | `thisArg` : `mapFn` 실행 시에 `this`로 사용할 값 18 | 19 | `return` : 새로운 `Array` 인스턴스 20 | 21 | ```js 22 | /* 단순히 배열로 바꾸고자 할 때 사용 */ 23 | const inputList = document.querySelector("input"); // NodeList 24 | const inputArray = Array.from(inputArray); 25 | 26 | /* 단순 반복문 대신 사용 */ 27 | const numberArray = Array.from({ length: 5 }, (value, index) => index); // [0, 1, 2, 3, 4], value는 항상 undefined 28 | // -> 이 방법 많이 씀!! 29 | ``` 30 | 31 | ## 인스턴스 메서드 32 | 33 | > 나름 자주 쓰던 순서대로 나열해보았다. 이 외에도 있음! 34 | 35 | ### 1. map(), forEach() 36 | 37 | ```js 38 | array.map(callback(currentValue[, index[, array]])[, thisArg]) 39 | array.forEach(callback(currentValue[, index[, array]])[, thisArg]) 40 | ``` 41 | 42 | `callback` : 각 요소를 시험할 함수 43 | 44 | `currentValue` : 처리할 현재 요소 45 | 46 | `index` : 처리할 현재 요소의 인덱스 47 | 48 | `array` : 메서드를 호출한 배열 49 | 50 | `thisArg` : `callback`을 실행할 때 `this`로 사용하는 값 51 | 52 | `return` : 53 | 54 | - `map()` : `callback`의 결과를 모은 새로운 배열 55 | - `forEach()` : `undefined` 56 | 57 | ```js 58 | /* 반복문 대신 많이 사용 */ 59 | const numberList = [1, 3, 5, 7, 9]; 60 | const newNumberList = numberList.map((number) => ++number); 61 | numberList.forEach((number) => { 62 | console.log(number); 63 | }); 64 | // 중간에 멈춰야 한다면, forEach 대신 some, every를 사용하자. 65 | ``` 66 | 67 | ### 2. filter 68 | 69 | ```js 70 | array.filter(callback(currentValue[, index[, array]])[, thisArg]) 71 | ``` 72 | 73 | `callback` : 각 요소를 시험할 함수. `true`를 반환하면 요소를 유지하고, `false`를 반환하면 버림 74 | 75 | `currentValue` : 처리할 현재 요소 76 | 77 | `index` : 처리할 현재 요소의 인덱스 78 | 79 | `array` : 메서드를 호출한 배열 80 | 81 | `thisArg` : `callback`을 실행할 때 `this`로 사용하는 값 82 | 83 | `return` : 테스트를 통과한 요소로 이루어진 새로운 배열 84 | 85 | ```js 86 | /* 단순 필터링 또는 검색할 때 */ 87 | const itemExceptColaList = itemList.filter((item) => item.Name !== "Cola"); 88 | // length 속성을 이용해서 개수 셀 때도 사용 가능 89 | ``` 90 | 91 | ### 3. every(), some() 92 | 93 | ```js 94 | array.every(callback(currentValue[, index[, array]])[, thisArg]) 95 | array.some(callback(currentValue[, index[, array]])[, thisArg]) 96 | ``` 97 | 98 | `callback` : 각 요소를 시험할 함수 99 | 100 | `currentValue` : 처리할 현재 요소 101 | 102 | `index` : 처리할 현재 요소의 인덱스 103 | 104 | `array` : 메서드를 호출한 배열 105 | 106 | `thisArg` : `callback`을 실행할 때 `this`로 사용하는 값 107 | 108 | `return` : 109 | 110 | - `every()` : `callback`이 **모든** 배열 요소에 대해 참인(truthy) 값을 반환하는 경우 `true`, 그 외엔 `false` 111 | - `some()` : `callback`이 **어떤** 배열 요소에 대해 참인(truthy) 값을 반환하는 경우 `true`, 그 외엔 `false` 112 | 113 | ```js 114 | /* 유효성 판별할 때 사용 */ 115 | const isAlreadyExist = itemList.some((item) => input.value === item.Name); 116 | 117 | /* 반복문 대신 사용 */ 118 | itemList.every((item) => { 119 | if (item.Name === "Kim") return false; // break 같은 역할! 120 | if (item.Name === "Son") return true; // continue 같은 역할! 121 | return true; 122 | }); 123 | ``` 124 | 125 | ### 4. includes() 126 | 127 | ```js 128 | array.includes(valueToFind[, fromIndex]) 129 | ``` 130 | 131 | `valueToFind` : 탐색할 요소 132 | 133 | `fromIndex` : 배열에서 검색을 시작할 위치 134 | 135 | `return` : 존재하면 `true`, 그 외엔 `false` 136 | 137 | ```js 138 | /* 유효성 판별할 때 사용 */ 139 | const isAlreadyExist = itemList.includes(name); 140 | ``` 141 | 142 | ### 5. join(), split() 143 | 144 | > `split()`은 `String` 인스턴스 메서드지만 자주 같이 쓰여서 넣음! 145 | 146 | ```js 147 | array.join([separator]); 148 | string.split([separator[, limit]]) 149 | ``` 150 | 151 | `separator` : 152 | 153 | - `join()`: 배열의 각 요소를 구분할 문자열 지정 154 | - `split()`: 원본 문자열을 끊어야 할 부분을 나타내는 문자열 155 | 156 | `limit` : 끊어진 문자열의 최대 개수 157 | 158 | `return` : 159 | 160 | - `join()` : 모든 요소들을 연결한 하나의 문자열을 반환 161 | - `split()` : 주어진 문자열을 분리한 부분 문자열을 담은 배열 162 | 163 | ```js 164 | const winnerList = ["A", "B", "C", "D"]; 165 | const winnerResult = winnerList.join(", "); // 'A, B, C, D' 166 | const winners = winnerResult.split(", "); // ['A', 'B', 'C', 'D'] 167 | ``` 168 | 169 | ### 6. reduce() 170 | 171 | ```js 172 | array.reduce(callback(accumulator, currentValue[, currentIndex[, array ]])[, initialValue]) 173 | ``` 174 | 175 | `callback` : 각 요소에 대해 실행할 함수 176 | 177 | `accumulator` : 콜백의 반환값을 누적 178 | 179 | `currentValue` : 처리할 현재 요소 180 | 181 | `currentIndex` : 처리할 현재 요소의 인덱스 182 | 183 | `array` : 메서드를 호출한 배열 184 | 185 | `initialValue` : 최초 호출에서 첫 번째 인수에 제공하는 값 186 | 187 | `return` : 누적 계산의 결과 값 188 | 189 | ```js 190 | /* 합 구할 때 가장 많이 사용 */ 191 | const numberList = [1, 2, 3, 4, 5]; 192 | const sum = numberList.reduce((acc, number) => acc + number, 0); // 15 193 | 194 | /* 오브젝트 초기화 할 때도 사용 */ 195 | const numberList = [1, 2, 3, 4, 5]; 196 | const initialObj = numberList.reduce((acc, number, index) => { 197 | acc[index] = number; 198 | return acc; 199 | }, {}); 200 | ``` 201 | 202 | ### 7. pop(), push() 203 | 204 | ```js 205 | array.pop() 206 | array.push(element1[, ...[, elementN]]) 207 | ``` 208 | 209 | `element` : 배열의 끝에 추가할 요소 210 | 211 | `return` : 212 | 213 | - `pop()` : 배열에서 제거한 요소 214 | - `push()` : 호출한 배열의 새로운 length 속성 215 | 216 | ### 8. slice() 217 | 218 | > 얕은 복사를 할 수 있음 219 | 220 | ```js 221 | array.slice([begin[, end]]) 222 | ``` 223 | 224 | `begin` : 추출 시작점에 대한 인덱스 225 | 226 | `end` : 추출을 종료 할 인덱스, `end`인덱스를 제외하고 추출 227 | 228 | `return` : 추출한 요소를 포함한 새로운 배열 229 | 230 | ```js 231 | const fruits = ["Banana", "Orange", "Lemon", "Apple", "Mango"]; 232 | const citrus = fruits.slice(1, 3); // ['Orange', 'Lemon'] 233 | ``` 234 | 235 | ### 9. find(), findIndex() 236 | 237 | ```js 238 | array.find(callback(currentValue[, index[, array]])[, thisArg]) 239 | array.findIndex(callback(currentValue[, index[, array]])[, thisArg]) 240 | ``` 241 | 242 | `callback` : 각 요소를 시험할 함수 243 | 244 | `currentValue` : 처리할 현재 요소 245 | 246 | `index` : 처리할 현재 요소의 인덱스 247 | 248 | `array` : 메서드를 호출한 배열 249 | 250 | `thisArg` : `callback`을 실행할 때 `this`로 사용하는 값 251 | 252 | `return` : 253 | 254 | - `find()` : 주어진 `callback`을 만족하는 **첫 번째 요소의 값**, 그 외엔 `undefined` 255 | - `findIndex()` : 주어진 `callback`을 만족하는 **첫 번째 요소의 인덱스**, 그 외엔 `-1` 256 | 257 | ```js 258 | /* 요소 찾을 때 사용 */ 259 | const selectedItem = itemList.find((item) => item.Name === input.value); 260 | const selectedItemIndex = itemList.findIndex((item) => item.Name === input.value); 261 | 262 | /* 탐색 중 삭제된 배열 요소에도 callbcak 호출됨 */ 263 | itemList.find((value, index) => { 264 | if (index == 0) { 265 | delete a[5]; 266 | } 267 | console.log(`index: ${index}, value: ${value}`); // 5번째 인덱스에서 value: undefined가 출력됨 268 | } 269 | ``` 270 | 271 | --- 272 | 273 | ## 참고 자료 274 | 275 | [**MDN: 배열 정적 메서드**](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array#%EC%A0%95%EC%A0%81_%EB%A9%94%EC%84%9C%EB%93%9C) 276 | 277 | [**MDN: 배열 인스턴스 메서드**](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array#%EC%9D%B8%EC%8A%A4%ED%84%B4%EC%8A%A4_%EB%A9%94%EC%84%9C%EB%93%9C) 278 | 279 | --- 280 | 281 | ## 더 공부하기 282 | 283 | - 유용한 객체 메서드 284 | - mutable, immutable 285 | 286 | > 메서드 사용 원리가 궁금하다면! 287 | 288 | - static 289 | - instance 290 | - prototype, \_\_proto\_\_ 291 | -------------------------------------------------------------------------------- /Level1/[미션0] 계산기/useful-object-method.md: -------------------------------------------------------------------------------- 1 | # 유용한 객체 메서드 2 | 3 | > 배열 메서드보단 덜 쓰지만 그래도 썼던 것들 모음! 당연히 이것들보단 훨씬 많음 4 | 5 | ## 정적 메서드 6 | 7 | ### 1. Object.entries(), Object.keys(), Object.values() 8 | 9 | ```js 10 | Object.entries(obj); 11 | Object.keys(obj); 12 | Object.values(obj); 13 | ``` 14 | 15 | `obj` : 객체 16 | 17 | `return` : 18 | 19 | - `entries()` : `obj`의 `[key, value]` 쌍 배열 20 | - `keys()` : `obj`의 `key` 배열 21 | - `values()` : `obj`의 `value` 배열 22 | 23 | ```js 24 | /* 객체를 순회하고 싶을 때 사용 */ 25 | Object.keys(item).forEach((key) => { 26 | if (key === "name") { 27 | item[key] = "KIM"; 28 | } 29 | }); 30 | 31 | Object.entries(item).forEach(([key, value]) => { 32 | console.log(key, value); 33 | }); 34 | ``` 35 | 36 | ### 2. Object.freeze() 37 | 38 | ```js 39 | Object.freeze(obj); 40 | ``` 41 | 42 | `obj` : 동결할 객체 43 | 44 | `return` : `freeze()`에 전달된 `obj`, 사본이 아니라 원본 그대로 반환 45 | 46 | ```js 47 | /* 상수로 분리한 객체를 더 '완벽하게' 지켜야 할 필요가 있을 때 */ 48 | const NUMBER_RANGE = Object.freeze({ 49 | MIN: 0, 50 | MAX: 9, 51 | }); // 이제 속성도 못 바꿈 52 | // -> 오버스펙일 수 있음. 꼭 필요한 게 아니라면 굳이..? 53 | ``` 54 | 55 | --- 56 | 57 | ## 참고 자료 58 | 59 | [**MDN: 객체 정적 메서드**](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object#%EC%A0%95%EC%A0%81_%EB%A9%94%EC%84%9C%EB%93%9C) 60 | 61 | --- 62 | 63 | ## 더 공부하기 64 | 65 | - 유용한 배열 메서드 66 | 67 | > 메서드 사용 원리가 궁금하다면! 68 | 69 | - static 70 | - instance 71 | - prototype, \_\_proto\_\_ 72 | -------------------------------------------------------------------------------- /Level1/[미션0] 계산기/var.md: -------------------------------------------------------------------------------- 1 | # var 2 | 3 | > ~~웬만하면~~ 쓰지 않는 게 좋다! 구버전을 지원하기 위해서 어쩔 수 없을 수도 있겠지만..! 4 | 5 | ## 구문 및 정의 6 | 7 | ```js 8 | var varname1 [= value1 [, varname2 [, varname3 ... [, varnameN]]]]; 9 | ``` 10 | 11 | `varname` : 변수명, 식별자 12 | 13 | `value` : 변수 초기값 14 | 15 | --- 16 | 17 | ## 변수 선언 18 | 19 | - 데이터가 담길 메모리 공간 확보 20 | - 확보한 메모리 공간의 주소를 담음 21 | - 변수명(식별자)을 통해 해당 데이터에 접근할 수 있음 22 | 23 | ## 변수 선언을 해야 하는 이유 24 | 25 | ### 1. 선언하지 않은 변수는 항상 전역 변수 26 | 27 | ```js 28 | function x() { 29 | y = 1; 30 | var z = 2; 31 | } 32 | 33 | x(); 34 | 35 | console.log(y); // 1 36 | console.log(z); // ReferenceError: z is not defined 37 | ``` 38 | 39 | ### 2. 선언하지 않은 변수는 할당문이 실행되기 전까지 존재하지 않음 40 | 41 | ```js 42 | console.log(a); // ReferenceError: a is not defined 43 | console.log("still going..."); // 실행되지 않음 44 | 45 | var a; 46 | console.log(a); // undefined 47 | console.log("still going..."); // 실행됨 48 | ``` 49 | 50 | ### 3. 선언하지 않은 변수는 실행 컨텍스트 속성에서 변경 가능(configurable) 51 | 52 | ```js 53 | var a = 1; 54 | b = 2; 55 | 56 | delete this.a; // 실패 -> 선언된 변수는 non-configurable 57 | delete this.b; // 성공 -> b는 실행 컨텍스트(객체) 속성에서 제거됨 58 | 59 | console.log(a, b); // ReferenceError: b is not defined 60 | ``` 61 | 62 | ## 특징 63 | 64 | ### 1. 중복 선언 허용 65 | 66 | - 같은 스코프 내에서도 중복 선언 허용 67 | 68 | ```js 69 | var x = 1; 70 | var y = 1; 71 | 72 | var x = 100; 73 | var y; // 초기화문이 없는 변수 선언문은 무시 74 | 75 | console.log(x); // 100 76 | console.log(y); // 1 77 | ``` 78 | 79 | ### 2. 함수 레벨 스코프 80 | 81 | - 오직 함수의 블록만을 로컬 스코프로 인정 82 | - 함수 내부가 아닌 if문, for문 등의 블록 내에서 선언하면 전역 변수 83 | 84 | ```js 85 | var x = 1; // 전역 변수 86 | 87 | // if문 블럭 88 | if (true) { 89 | var x = 100; // 전역 변수 90 | } 91 | 92 | console.log(x); // 100 93 | ``` 94 | 95 | ### 3. 변수 호이스팅 96 | 97 | - 마치 변수 선언문이 코드의 맨 윗단으로 끌어 올려진 것처럼 동작하는 현상 98 | - 코드가 실행되기 전, 자바스크립트 엔진은 이미 실행 환경의 변수명을 알고 있음(평가 과정) 99 | - var는 평가 과정에서, 선언 단계와 초기화 단계(undefined로 초기화)가 동시에 이뤄짐 100 | 101 | ```js 102 | console.log(x); // undefined 103 | 104 | x = 100; 105 | 106 | console.log(x); // 100 107 | 108 | var x; // 호이스팅 발생 109 | 110 | console.log(x); // 100 111 | ``` 112 | 113 | ## 문제점 114 | 115 | ### 1. 중복 선언 허용으로 인한 예상치 못한 결과 발생 116 | 117 | ```js 118 | /* 개발자 A가 작성한 코드 */ 119 | var answer = "이 문장은 바뀌면 안 됩니다."; 120 | 121 | /* ... 수만 줄의 코드 ... */ 122 | 123 | /* 개발자 B가 작성한 코드 */ 124 | var answer = 1; 125 | 126 | console.log(answer); // 1 127 | ``` 128 | 129 | ### 2. 함수 레벨 스코프로 인한, 의도치 않은 전역 변수 선언 130 | 131 | ### 3. 호이스팅으로 인해 떨어지는 가독성 132 | 133 | ```js 134 | /* 실행 순서대로 재배치 */ 135 | var x; 136 | 137 | console.log(x); // undefined 138 | 139 | x = 100; 140 | 141 | console.log(x); // 100 142 | 143 | console.log(x); // 100 144 | ``` 145 | 146 | ### 4. 선언 전 호출이 가능하기 때문에, 오류 발생 가능성 증가 147 | 148 | --- 149 | 150 | ## 예제 151 | 152 | ```js 153 | /* 여러 변수 선언 및 초기화 */ 154 | var x, y; 155 | var a = 0, 156 | b = 0; 157 | 158 | /* 단일 값으로 여러 변수 할당 */ 159 | var a = "A"; 160 | var b = a; 161 | // 또는 162 | var a, 163 | b = (a = "A"); 164 | // 순서 주의 165 | var x = y, 166 | y = "A"; // x: undefined, y: "A" 167 | ``` 168 | 169 | --- 170 | 171 | ## 참고 자료 172 | 173 | [**MDN: var**](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Statements/var) 174 | 175 | **『코어 자바스크립트』** **_정재남 지음_** 176 | 177 | **『모던 자바스크립트 Deep Dive』** **_이웅모 지음_** 178 | 179 | --- 180 | 181 | ## 더 공부하기 182 | 183 | - let 184 | - const 185 | - scope 186 | - execution context 187 | -------------------------------------------------------------------------------- /Level1/[미션1] 자동차 경주/class.md: -------------------------------------------------------------------------------- 1 | # class 2 | 3 | > 구조 설계할 때나, 구현할 때 클래스를 본격적으로 사용할 텐데, 뭔지는 알고 쓰자! 4 | 5 | ## 정의 6 | 7 | 인스턴스를 생성하기 위한 틀, 템플릿 8 | 9 | JS에서 클래스는 프로토타입을 이용해서 만들어짐 10 | 11 | JS 클래스는 함수 객체 12 | 13 | ```js 14 | // 1. 클래스 선언식 15 | class Rectangle { 16 | ... 17 | } 18 | 19 | // 2. 클래스 표현식 20 | let Rectangle = class { 21 | ... 22 | }; 23 | console.log(typeof Rectangle); // function 24 | ``` 25 | 26 | --- 27 | 28 | ## 특징 29 | 30 | - 호출시 `new` 연산자 필수 31 | - 상속 지원 키워드(`extends`, `super`) 제공 32 | - TDZ(Temporal Dead Zone) 존재 33 | - 재정의 불가능 34 | - 클래스 바디의 모든 코드는 strict mode 35 | - 클래스의 모든 속성은 열거 불가능(`[[Enumerable]]`이 `false`) 36 | 37 | ## 메서드(method) 38 | 39 | - 메서드 축약 표현 사용 40 | - 콤마(,) 필요 없음 41 | - strict mode 42 | - 열거 불가능 43 | - non-constuctor 44 | 45 | ### constructor 46 | 47 | 인스턴스를 생성하고 초기화하기 위한 특수 메서드 48 | 49 | ```js 50 | class Rectangle { 51 | // constructor 메서드 52 | constructor(width, height) { 53 | this.width = width; 54 | this.height = height; 55 | } 56 | } 57 | ``` 58 | 59 | - 이름 변경 불가능 60 | - 클래스 정의가 평가된 후, `constructor` 메서드에 작성된 동작을 하는 함수 객체가 생성됨 61 | - 클래스 내에 최대 한 개 62 | - 생략할 시, 빈 `constructor`가 정의됨 63 | - 내부에서 `this`에 인스턴스 속성을 추가할 수 있음 64 | - 암묵적으로 `this`에 바인딩 된 인스턴스를 반환하기 때문에, 별도의 반환문이 없어야 함 65 | 66 | ### 프로토타입(prototype) 메서드 67 | 68 | 인스턴스가 상속받아 사용하는 메서드 69 | 70 | ```js 71 | class Rectangle { 72 | constructor(width, height) { 73 | this.width = width; 74 | this.height = height; 75 | } 76 | 77 | // prototype 메서드 78 | getArea() { 79 | return this.width * this.height; 80 | } 81 | } 82 | 83 | const rectangle = new Rectangle(2, 3); 84 | console.log(rectangle.getArea()); // 6 85 | ``` 86 | 87 | - 클래스 바디에 작성 88 | - 클래스의 `prototype` 객체의 속성 89 | - 인스턴스 `[[Prototype]]`이 클래스 `prototype` 참조 90 | - 호출시 메서드 내부의 `this`는 인스턴스를 가리킴 91 | 92 | ### 정적(static) 메서드 93 | 94 | 인스턴스를 생성하지 않고, 클래스로 호출하는 메서드 95 | 96 | ```js 97 | class Rectangle { 98 | constructor(width, height) { 99 | this.width = width; 100 | this.height = height; 101 | } 102 | 103 | // static 메서드 104 | static sayType() { 105 | console.log("직사각형!"); 106 | } 107 | 108 | getArea() { 109 | return this.width * this.height; 110 | } 111 | } 112 | 113 | Rectangle.sayType(); // 직사각형! 114 | ``` 115 | 116 | - 메서드에 `static` 키워드 사용 117 | - 클래스 자체 속성 118 | - 인스턴스의 프로토타입 체인을 따라 접근할 수 없음 119 | - 메서드 내에서 인스턴스 속성을 참조할 수 없음 120 | > airbnb eslint rule을 사용하다보면, this를 사용하지 않는 메서드를 static으로 바꾸라는 경고가 뜨는데, 요런 특징 때문이기도 함! 121 | - 호출시 메서드 내부의 `this`는 클래스를 가리킴 122 | - util 함수를 전역으로 정의하지 않고, 메서드로 구조화할 때 유용 123 | > 그런데, 어떤 클래스가 static method로만 이뤄져 있다면 굳이 클래스를 써야할지 생각해보기! 그냥 객체나 함수로 충분하지 않을까? 124 | 125 | ## 속성(property) 126 | 127 | ### 인스턴스(instance) 속성 128 | 129 | 말 그대로, 인스턴스의 속성 130 | 131 | ```js 132 | class Rectangle { 133 | constructor(width, height) { 134 | // instance 속성 135 | this.width = width; 136 | this.height = height; 137 | } 138 | } 139 | ``` 140 | 141 | - `constructor` 내부에서 `this`에 추가 142 | - 특정 키워드가 없으면 언제나 `public` 143 | 144 | ### 접근자(getter, setter) 속성 145 | 146 | 자체적인 값 없이, 다른 데이터 속성의 값을 읽거나 변경할 때 사용하는 접근자 함수(accessor function)로 구성 147 | 148 | ```js 149 | class Person { 150 | constructor(firstName, lastName) { 151 | this.firstName = firstName; 152 | this.lastName = lastName; 153 | } 154 | 155 | // getter 156 | get fullName() { 157 | return `${this.firstName} ${this.lastName}`; 158 | } 159 | 160 | // setter 161 | set fullName(name) { 162 | [this.firstName, this.lastName] = name.split(" "); 163 | } 164 | } 165 | 166 | const person = new Person("KIM", "TAETAE"); 167 | console.log(person.fullName); // KIM TAETAE 168 | 169 | person.fullName = "KIM NANNOO"; 170 | console.log(person.fullName); // KIM NANNOO 171 | ``` 172 | 173 | - 프로토타입의 속성 174 | - getter: 인스턴스 속성에 접근할 때, 속성 값을 조작하거나 별도의 행위가 필요할 때 사용. 반환값 필수 175 | - setter: 인스턴스 속성 값을 변경할 때, 속성 값을 조작하거나 별도의 행위가 필요할 때 사용. 매개변수(1개) 필수 176 | 177 | ## field(member) 선언 178 | 179 | > 실험적 기능이지만, 크롬 등에선 쓸 수 있음. Java같은 다른 언어에선 이미 사용 중! TS는 기본적으로 사용하는 듯..? 180 | 181 | - 모든 클래스 필드는 인스턴스의 속성 182 | - 필드 참조 시 `this`로 접근 필수 183 | - 클래스 바디에 필드 선언 시에는 `this` 불필요 184 | - 외부 값으로 필드를 초기화할 때는 `constructor` 내부에서 초기화 185 | > 이런 경우엔 굳이 필드로 선언할 필요 없음(self-documenting 목적이 아니라면) 186 | - 클래스 필드로 메서드 정의 가능 187 | 188 | > 단, 이렇게 하면 프로토타입 메서드가 아닌 인스턴스 메서드가 됨!! 인스턴스가 많아질수록 메모리를 많이 쓰게 됨. -> 메서드를 필드로 작성하는 것은 권장하지 않음. 189 | 190 | > 필드로 화살표 함수를 선언해서 this 바인딩을 해결할 수도 있음. 이벤트리스너 콜백 함수 필드 메서드로 정의할 때 많이 썼음! 191 | 192 | - `static` 키워드 사용 가능 193 | 194 | ### public 195 | 196 | 특정 키워드가 없으면 항상 public 197 | 198 | ```js 199 | class Rectangle { 200 | type = "직사각형"; 201 | } 202 | 203 | const rectangle = new Rectangle(); 204 | console.log(rectangle.type); // 직사각형 205 | ``` 206 | 207 | - 클래스 내부, 자식 클래스 내부, 클래스 인스턴스에서 접근 가능 208 | 209 | ### private 210 | 211 | `#`을 붙여 클래스 외부에서 참조할 수 없도록 함 212 | 213 | ```js 214 | class Rectangle { 215 | #type = "직사각형"; 216 | 217 | constructor() { 218 | console.log(this.#type); // 직사각형 219 | } 220 | 221 | get type() { 222 | return this.#type; 223 | } 224 | } 225 | 226 | const rectangle = new Rectangle(); 227 | console.log(rectangle.#type); // SyntaxError: Private field '#type' must be declared in an enclosing class 228 | console.log(rectangle.type); // 직사각형 229 | ``` 230 | 231 | - 해당 필드가 선언된 클래스(자식 클래스 불포함)에서만 접근 가능 232 | - 접근자 함수를 통해 간접 접근 가능 233 | 234 | ## 상속 235 | 236 | 기존 클래스를 확장해 새로운 클래스를 정의 237 | 238 | > extends와 implements는 다른 거! js에서 클래스 상속(extends)을 interface implements처럼 사용하지 말장 239 | 240 | > 상속은 주로 여러 클래스가 공통된 부분이 있을 때 중복을 줄이기 위해 쓰는 것 같음 241 | 242 | ```js 243 | class Animal { 244 | constructor(name) { 245 | this.name = name; 246 | } 247 | 248 | eat() { 249 | console.log(`${this.name} eat`); 250 | } 251 | 252 | move() { 253 | console.log(`${this.name} move`); 254 | } 255 | } 256 | 257 | class Bird extends Animal { 258 | fly() { 259 | console.log(`${this.name} fly`); 260 | } 261 | } 262 | 263 | const bird = new Bird("독수리"); 264 | 265 | console.log(bird.eat(), bird.move(), bird.fly()); // 독수리 eat, 독수리 move, 독수리 fly 266 | ``` 267 | 268 | - `extends` 키워드로 상속 269 | - 부모 클래스 속성을 물려받음 + 자신만의 고유 속성 추가 270 | - 코드 재사용 관점에서 유용 271 | - 인스턴스 프로토타입 체인뿐만 아니라, 클래스 프로토타입 체인도 생성: static, prototype 메서드와 속성 모두 상속 가능 272 | 273 | ### super 274 | 275 | 부모클래스 `constructor` 호출(`super()`) 또는, 부모클래스 메서드 호출(`super.method()`) 가능 276 | 277 | ```js 278 | class Parent { 279 | constructor(x, y) { 280 | this.x = x; 281 | this.y = y; 282 | } 283 | } 284 | 285 | class Child extends Parent { 286 | constructor(x, y, z) { 287 | super(x, y); 288 | this.z = z; 289 | } 290 | } 291 | ``` 292 | 293 | - 자식클래스 `constructor`를 생략하지 않는 경우, `constructor`에서 호출 필수 294 | - 호출 전에 `this` 참조 불가능 295 | 296 | > 자식클래스는 인스턴스를 직접 생성하지 않고, 부모클래스에게 super를 호출해서 인스턴스 생성 과정을 위임하기 때문 297 | 298 | --- 299 | 300 | ## 참고 자료 301 | 302 | [**MDN: class**](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Classes) 303 | 304 | **『모던 자바스크립트 Deep Dive』** **_이웅모 지음_** 305 | 306 | --- 307 | 308 | ## 더 공부하기 309 | 310 | - prototype 311 | - prototype chain 312 | - strict mode 313 | - this 314 | -------------------------------------------------------------------------------- /Level1/[미션1] 자동차 경주/strict-mode.md: -------------------------------------------------------------------------------- 1 | # strict mode 2 | 3 | > JS는 모드같은 것도 있음.. 일부만 지원하거나, 지원하지 않는 브라우저도 있기 때문에 사용 주의!! 4 | 5 | > eslint가 거의 다 잡아줌. eslint 사용하자! 6 | 7 | ## 정의 8 | 9 | 오류를 발생시킬 가능성이 높거나, 자바스크립트 엔진의 최적화 작업에 문제를 일으킬 수 있는 코드에 대해 명시적인 에러를 발생시킴 10 | 11 | ```js 12 | "use strict"; 13 | 14 | function foo() { 15 | x = 10; 16 | } 17 | 18 | foo(); 19 | ``` 20 | 21 | - `'use strict'` 또는 `"use strict"`를 전역 또는 함수 바디의 앞쪽에 추가 22 | 23 | --- 24 | 25 | ## 문제점 26 | 27 | - 전역에 적용한 strict mode는 script 단위로 적용되는데, strict mode와 non-strict mode script를 혼용하면 [오류 발생](https://bugzilla.mozilla.org/show_bug.cgi?id=579119) 가능 28 | - 함수에 적용한 strict mode도 마찬가지 29 | - strict mode는 semantic을 바꾸기 때문에, 사용하는 데에 주의해야 함 30 | 31 | ## strict mode에서 발생하는 에러 케이스 32 | 33 | ### Reference Error 34 | 35 | - 암묵적 전역 36 | 37 | ```js 38 | (function () { 39 | "use strict"; 40 | 41 | x = 1; 42 | console.log(x); // ReferenceError: x is not defined 43 | })(); 44 | ``` 45 | 46 | ### Type Error 47 | 48 | - non-strict mode에서 조용히 실패하고 넘어가는 할당 49 | 50 | - 쓸 수 없는 전역 또는 프로퍼티에 할당 51 | - getter-only 프로퍼티에 할당 52 | - 확장 불가 객체에 새 프로퍼티 할당 53 | 54 | ```js 55 | "use strict"; 56 | 57 | // 1. TypeError: Cannot assign to read only property 'undefined' of object '#' 58 | var undefined = 5; 59 | var Infinity = 5; 60 | var obj1 = {}; 61 | Object.defineProperty(obj1, "x", { value: 42, writable: false }); 62 | obj1.x = 9; 63 | 64 | // 2. TypeError: Cannot set property x of # which has only a getter 65 | var obj2 = { 66 | get x() { 67 | return 17; 68 | }, 69 | }; 70 | obj2.x = 5; 71 | 72 | // 3. TypeError: Cannot add property newProp, object is not extensible 73 | var fixed = {}; 74 | Object.preventExtensions(fixed); 75 | fixed.newProp = "ohai"; 76 | ``` 77 | 78 | - 원시값에 속성 설정 79 | 80 | ```js 81 | (function () { 82 | "use strict"; 83 | 84 | false.true = ""; // TypeError: Cannot create property 'true' on boolean 'false' 85 | })(); 86 | ``` 87 | 88 | ### Syntax Error 89 | 90 | - 변수, 함수, 매개변수의 삭제 91 | 92 | ```js 93 | (function () { 94 | "use strict"; 95 | 96 | var x = 1; 97 | delete x; // SyntaxError: Delete of an unqualified identifier in strict mode. 98 | })(); 99 | ``` 100 | 101 | - 매개변수 이름의 중복 102 | 103 | ```js 104 | (function () { 105 | "use strict"; 106 | 107 | // SyntaxError: Duplicate parameter name not allowed in this context 108 | function foo(x, x) { 109 | return x + x; 110 | } 111 | console.log(foo(1, 2)); 112 | })(); 113 | ``` 114 | 115 | - 8진 구문 116 | 117 | ```js 118 | (function () { 119 | "use strict"; 120 | var sum = 121 | 015 + // SyntaxError: Octal literals are not allowed in strict mode. 122 | 197 + 123 | 142; 124 | })(); 125 | ``` 126 | 127 | - with 문의 사용 128 | 129 | > `with`문은 사용하지 않는 게 좋다고 한다. 130 | 131 | ```js 132 | (function () { 133 | "use strict"; 134 | 135 | // SyntaxError: Strict mode code may not include a with statement 136 | with ({ x: 1 }) { 137 | console.log(x); 138 | } 139 | })(); 140 | ``` 141 | 142 | ## strict mode에서의 변화 143 | 144 | ### 일반 함수 `this` 145 | 146 | ```js 147 | (function () { 148 | "use strict"; 149 | 150 | function foo() { 151 | console.log(this); // undefined 152 | } 153 | 154 | foo(); 155 | })(); 156 | ``` 157 | 158 | - strict mode에서 함수를 일반 함수로 호출하면, `this`에 `undefined`가 바인딩 됨 159 | - 원래는 일반 함수로 호출하면 전역 객체(`window`, `global` 등)가 바인딩 됨 160 | 161 | ### `arguments` 객체 162 | 163 | ```js 164 | (function (x) { 165 | "use strict"; 166 | 167 | console.log(arguments); // Arguments [3, ...] 168 | 169 | x = 0; 170 | 171 | console.log(arguments); // Arguments [3, ...] 172 | })(3); 173 | ``` 174 | 175 | - strict mode에서는 매개변수에 전달된 인자를 재할당해서 변경해도, `arguments` 객체에 반영되지 않음 176 | 177 | --- 178 | 179 | ## 참고 자료 180 | 181 | [**MDN: strict mode**](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Strict_mode) 182 | 183 | **『모던 자바스크립트 Deep Dive』** **_이웅모 지음_** 184 | 185 | --- 186 | 187 | ## 더 공부하기 188 | 189 | - this 190 | 191 | > 자동으로 strict mode인 경우 192 | 193 | - class 194 | - module 195 | -------------------------------------------------------------------------------- /Level1/[미션2] 로또/this.md: -------------------------------------------------------------------------------- 1 | # this 2 | 3 | > `this` 잘 모르면 이벤트 핸들러 달면서 문제 꼭 겪게 됨ㅎㅎ 자세히 알아두기!! 4 | 5 | ## 구문 및 정의 6 | 7 | ```js 8 | this; 9 | ``` 10 | 11 | 실행 컨텍스트 속성으로, non-strict mode에선 항상 객체를 참조하고, 엄격 모드는 어떤 값이든 될 수 있음 12 | 13 | **함수를 호출한 주체**의 정보를 담는 속성, 자기 참조 변수 14 | 15 | `this`가 가리키는 값은 함수 호출 방식에 따라 결정 16 | 17 | --- 18 | 19 | ## 컨텍스트에 따른 this 20 | 21 | ### 전역 22 | 23 | ```js 24 | console.log(this); // Window 25 | ``` 26 | 27 | - strict mode 여부에 관계 없이, 항상 전역 객체를 참조 28 | - `globalThis` 속성으로 현재 실행 컨텍스트와 관계 없이 항상 전역 객체 참조 가능 29 | - 브라우저는 `window`, node.js 환경에서는 `global` 30 | 31 | ### 함수 32 | 33 | #### 1. 단순 호출 34 | 35 | ```js 36 | function foo() { 37 | console.log(this); 38 | } 39 | 40 | foo(); // Window 41 | ``` 42 | 43 | ```js 44 | function foo() { 45 | "use strict"; 46 | console.log(this); 47 | } 48 | 49 | foo(); // undefined 50 | ``` 51 | 52 | - non-strict mode: 전역 객체 참조 53 | > 이 부분 때문에 많이 헷갈림. 설계상의 오류라고도 함! 54 | - strict mode: `undefined` 55 | 56 | #### 2. 메서드로 호출 57 | 58 | ```js 59 | function foo() { 60 | console.log(this); 61 | console.log(this.myName); 62 | } 63 | 64 | const obj = { 65 | myName: "TaeTae", 66 | method: foo, 67 | }; 68 | 69 | foo(); // Window, undefined 70 | obj.method(); // {myName: 'TaeTae', method: ƒ}, TaeTae 71 | obj["method"](); // {myName: 'TaeTae', method: ƒ}, TaeTae 72 | ``` 73 | 74 | - `.` 또는 `[]` 앞의 객체를 참조 75 | 76 | #### 3. 생성자 함수로 호출 77 | 78 | ```js 79 | function Foo(myName) { 80 | this.myName = myName; 81 | console.log(this); 82 | console.log(this.myName); 83 | } 84 | 85 | Foo("TaeTae"); // Window, TaeTae 86 | const foo = new Foo("TaeTae"); // Foo {myName: 'TaeTae'}, TaeTae 87 | console.log(foo.myName); // TaeTae 88 | ``` 89 | 90 | - `new` 키워드로 호출시, 생성된 instance를 `this`에 바인딩 91 | - class도 마찬가지 92 | 93 | #### 4. 콜백 함수로 호출 94 | 95 | ```js 96 | function callback(e) { 97 | console.log(this); //
...
98 | console.log(e.currentTarget); //
...
99 | console.log(this === e.currentTarget); // true 100 | } 101 | 102 | const div = document.querySelector("div"); 103 | div.addEventListener("click", callback); 104 | ``` 105 | 106 | - 제어권을 가진 함수가 콜백에 `this`를 지정하는 경우에는 그 값 - 아닌 경우에는 단순 호출과 같음 107 | - `addEventListener` 메서드는 자신의 `this`를 넘겨주도록 정의되어 있기 때문에, 콜백함수의 `this`도 `.` 앞의 요소가 됨 108 | 109 | #### 5. 화살표 함수로 호출 110 | 111 | ```js 112 | function Foo() { 113 | this.myName = "TaeTae"; 114 | this.arrow = () => { 115 | console.log(this); 116 | console.log(this.myName); 117 | }; 118 | } 119 | 120 | const foo = new Foo(); 121 | foo.arrow(); // Foo {myName: 'TaeTae', arrow: ƒ}, TaeTae 122 | 123 | const obj = { 124 | myName: "TaeTae", 125 | arrow: () => { 126 | console.log(this); 127 | console.log(this.myName); 128 | }, 129 | }; 130 | 131 | obj.arrow(); // Window, undefined 132 | ``` 133 | 134 | - 자체 `this`를 가지고 있지 않아서, 자신을 감싼 lexical scope의 `this`를 참조 135 | - lexical scope: 함수가 **정의된 환경(위치)** 에 따라 상위 스코프에 대한 참조를 결정 136 | > 이 속성 때문에, 클래스에서 이벤트 리스너 콜백 함수를 정의할 때 프로토타입 메서드가 아닌, 화살표 함수(필드)로 정의하기도 함 137 | 138 | ## 명시적 this 바인딩 139 | 140 | ### `bind` 141 | 142 | ```js 143 | func.bind(thisArg[, arg1[, arg2[, ...]]]); 144 | ``` 145 | 146 | `func`: 타겟 함수 147 | `thisArg`: `func`의 `this`에 전달하는 값 148 | `arg`: `func`의 매개변수 앞에 사용될 인자 149 | `return`: 지정한 `this` 값 및 초기 인자를 사용하여 변경한 원본 함수(`func`)의 복제본 150 | 151 | ### `call` 152 | 153 | ```js 154 | func.call(thisArg[, arg1[, arg2[, ...]]]); 155 | ``` 156 | 157 | `func`: 타겟 함수 158 | `thisArg`: `func`의 `this`에 전달하는 값 159 | `arg`: `func`의 매개변수 앞에 사용될 인자 160 | `return`: `this`와 `arguments`를 매개로 호출된 함수의 반환값 161 | 162 | ### `apply` 163 | 164 | ```js 165 | func.apply(thisArg, [argsArray]); 166 | ``` 167 | 168 | `func`: 타겟 함수 169 | `thisArg`: `func`의 `this`에 전달하는 값 170 | `argsArray`: `func`의 인자를 지정하는 유사 배열 객체 171 | `return`: `this`와 `arguments`를 매개로 호출된 함수의 반환값 172 | 173 | ### 인자로 `this`를 받는 경우 174 | 175 | - 주로 반복 수행하는 배열 메서드(`forEach`, `map`, `filter`, ...)의 생략 가능한 두 번째 매개 변수(`thisArg`)에 지정 176 | 177 | --- 178 | 179 | ## 참고 자료 180 | 181 | [**MDN: this**](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Operators/this) 182 | 183 | **『코어 자바스크립트』** **_정재남 지음_** 184 | 185 | **『모던 자바스크립트 Deep Dive』** **_이웅모 지음_** 186 | 187 | --- 188 | 189 | ## 더 공부하기 190 | 191 | - scope 192 | - execution context 193 | - function 194 | - constructor function 195 | - arrow function 196 | - callback function 197 | - method 198 | -------------------------------------------------------------------------------- /Level2/[미션0] 계산기/first-class-object.md: -------------------------------------------------------------------------------- 1 | # 일급 객체 2 | 3 | > JS 함수가 일급 객체라는 소리 들어보긴 했는데.. 하지 말고 알아두자! 4 | 5 | ## 정의 6 | 7 | - 다른 객체들에 적용 가능한 연산을 모두 지원하는 객체 8 | 9 | - 다음의 조건을 만족해야 함 10 | 11 | 0. 함수가 일급 객체가 되기 위한 조건: 런타임에 생성 가능 12 | > 확실한 조건은 아닌 것 같다. 좀 더 조사가 필요! 13 | 1. 변수에 할당 가능 14 | 2. 함수 인자로 전달 가능 15 | 3. 함수 반환값으로 사용 가능 16 | 17 | ## 일급 함수 18 | 19 | - 자바스크립트의 함수는 일급 객체의 조건을 모두 만족하므로 일급 객체 20 | - 즉, 함수를 객체와 동일하게 사용할 수 있음 21 | - 다른 객체처럼 값으로 취급 가능 22 | - 다른 객체와 차이점은, 함수는 호출할 수 있음 23 | - JS 함수는 값을 사용할 수 있는 곳이라면 항상 리터럴로 정의할 수 있으며, 런타임에 함수 객체로 평가됨 24 | 25 | ### 특징 26 | 27 | 1. 변수에 함수 할당 28 | 29 | ```js 30 | const foo = function () {}; 31 | const bar = () => {}; 32 | const funcs = [foo, bar]; 33 | 34 | foo(); // 변수에 할당하여 함수를 호출할 수 있음 35 | bar(); 36 | ``` 37 | 38 | 2. 함수를 인자(argument) 및 매개변수(parameter)로 사용 39 | 40 | ```js 41 | function foo(func) { 42 | // parameter 43 | func(); 44 | } 45 | 46 | function bar() {} 47 | 48 | foo(bar); // argument -> 여기서 bar 함수는 콜백함수 49 | ``` 50 | 51 | 3. 함수를 함수 반환값으로 사용 52 | 53 | ```js 54 | // foo는 고차 함수 55 | function foo() { 56 | return function () {}; 57 | } 58 | 59 | foo(); // function () {} 60 | ``` 61 | 62 | --- 63 | 64 | ## 참고 자료 65 | 66 | [**MDN: 일급 함수**](https://developer.mozilla.org/ko/docs/Glossary/First-class_Function) 67 | 68 | [**MDN: 함수**](https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Functions) 69 | 70 | [**Wiki: 일급 객체**](https://ko.wikipedia.org/wiki/%EC%9D%BC%EA%B8%89_%EA%B0%9D%EC%B2%B4) 71 | 72 | **『모던 자바스크립트 Deep Dive』** **_이웅모 지음_** 73 | 74 | --- 75 | 76 | ## 더 공부하기 77 | 78 | - value, expression, statement 79 | 80 | - function 81 | 82 | - argument, parameter 83 | 84 | - callback 85 | 86 | - higher order function 87 | 88 | - closure 89 | -------------------------------------------------------------------------------- /Level2/[미션0] 계산기/value-expression-statement.md: -------------------------------------------------------------------------------- 1 | # value, expression, statement 2 | 3 | > 값, 식, 문이 어떤 차이가 있는 지 알아야 한다! 특히 문과 식을 헷갈리지 않도록 하자. 4 | 5 | ## 값 - value 6 | 7 | - 표현식에 의해 생성된 결과 8 | 9 | - 모든 값은 데이터 타입을 가지고, 메모리에 저장됨 10 | 11 | > 메모리에 0100 0001이 저장되어 있더라도, 데이터 타입에 따라 65가 될 수도, 'A'가 될 수도 있음! 12 | 13 | - 변수에 할당됨 14 | 15 | ## 리터럴 - lieteral 16 | 17 | - 문자 또는 기호를 사용해 값을 생성하는 표기법 18 | 19 | ```js 20 | // 숫자 리터럴 21 | 10 3.5 0b1010 0o101 0x14 22 | 23 | // 문자 리터럴 24 | 'hi' "HI" `hihi` 25 | 26 | // 불리언 리터럴 27 | true false 28 | 29 | // 객체 리터럴 30 | {} {1: 2, 2: 4} 31 | 32 | // 배열 리터럴 33 | [] [1, 2] 34 | 35 | // 함수 리터럴 36 | function() {} 37 | () => {} 38 | 39 | // 정규 표현식 리터럴 40 | /[]/g 41 | 42 | // 그 외 43 | null undefined class 44 | ``` 45 | 46 | ## (표현)식 - expression 47 | 48 | - 값으로 평가될 수 있는 문 49 | 50 | - 표현식이 평가되면 새로운 값을 생성하거나, 기존 값을 참조 51 | 52 | - 리터럴, 식별자, 연산자, 함수 호출 등의 조합으로 이뤄짐 53 | 54 | - 표현식은 값처럼 사용할 수 있음. 즉, 값이 위치할 수 있는 곳엔 표현식도 위치할 수 있음 55 | 56 | ```js 57 | // 리터럴 표현식 58 | 1 '안녕' 59 | 60 | // 식별자 표현식 61 | sum 62 | person.name 63 | array[0] 64 | 65 | // 연산자 표현식 66 | 10 + 20 67 | x = 7 // -> 7로 평가됨 68 | 69 | // 함수 호출 표현식 70 | say() 71 | person.getAge() 72 | ``` 73 | 74 | ## (명령)문 - statement 75 | 76 | - 프로그램을 구성하는 기본 단위이자 최소 실행 단위 77 | 78 | - 문은 토큰으로 구성 79 | 80 | - 토큰(token): 문법적으로 더 이상 나눌 수 없는 코드 요소 81 | - 키워드, 식별자, 리터럴, 연산자 등 82 | 83 | - 선언문, 할당문, 조건문, 반복문 등이 있음 84 | 85 | ## 표현식과 문 86 | 87 | - 문에는 값으로 평가되지 않는, 즉 표현식이 아닌 문이 존재 88 | 89 | - 표현식이 아닌 문은 변수에 할당할 수 없음 90 | 91 | ```js 92 | // 선언문 93 | let x; // undefined 94 | 95 | let y = let x; // Uncaught SyntaxError: Unexpected identifier 96 | 97 | // 할당문 98 | x = 10; // 10 99 | 100 | let y = (x = 10); // y는 10을 참조 101 | 102 | // 조건문 103 | if(x) {} // undefined 104 | 105 | let y = if(x) {}; // Uncaught SyntaxError: Unexpected token 'if' 106 | 107 | // 반복문 108 | for(x; x < 10; x++) {} // undefined 109 | 110 | let y = for(x; x < 10; x++) {}; // Uncaught SyntaxError: Unexpected token 'for' 111 | 112 | ``` 113 | 114 | > 잘 모르겠을 때는 크롬 개발자도구 콘솔창에 입력하면 된다! 문이면 undefined가 뜬다. 115 | 116 | --- 117 | 118 | ## 참고 자료 119 | 120 | [**MDN: 표현식과 연산자**](https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Expressions_and_Operators) 121 | 122 | [**MDN: 식 및 연산자**](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators) 123 | 124 | **『모던 자바스크립트 Deep Dive』** **_이웅모 지음_** 125 | 126 | --- 127 | 128 | ## 더 공부하기 129 | 130 | - data type 131 | - first class object 132 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # js-dictionary 2 | 우테코 과정을 겪으면서 필요한 태태만의 자바스크립트 지식 사전 3 | 4 | ## 가이드 5 | 1. 브랜치에서 각 주제에 대한 초안 작성 후, `draft` 브랜치에 머지합니다. 최종안만 `main`에 머지하는 방식으로 진행됩니다. 6 | * 브랜치 이름은 `작성할 개념 및 주제`입니다. 7 | * ***ex) this*** 8 | 9 | 2. 각 document에는 다음의 요소가 포함됩니다. 10 | * 구문 및 정의 11 | * 설명 12 | * 예제 13 | * 참고 자료 14 | * 더 공부하기 15 | 16 | 3. document에 작성자의 생각이 포함될 수 있습니다. 17 | 18 | 4. 새로 작성한 document는 [INDEX](https://github.com/nan-noo/js-dictionary/blob/main/INDEX.md) 문서에 추가됩니다. 19 | --------------------------------------------------------------------------------