diff --git "a/07\355\232\214\354\260\250(26\354\236\245~28\354\236\245)/\353\205\270\355\230\204\354\240\225.md" "b/07\355\232\214\354\260\250(26\354\236\245~28\354\236\245)/\353\205\270\355\230\204\354\240\225.md" new file mode 100644 index 0000000..1a434c6 --- /dev/null +++ "b/07\355\232\214\354\260\250(26\354\236\245~28\354\236\245)/\353\205\270\355\230\204\354\240\225.md" @@ -0,0 +1,580 @@ +# 26장 ES6 함수의 추가 기능 + +## 26.1. 함수의 구분 + +```jsx +var foo = function () { + return 1; +} + +// 일반 함수로서 호출 +foo(); // 1 + +// 생성자 함수로서 호출 +new foo(); // -> foo {} + +// 메서드로서 호출 +var obj = { foo: foo }; +obj.foo(); // 1 +``` + +```jsx +var foo = function () {}; + +foo(); // undefined +new foo(); // foo {} +``` + + **주의🚨**  + +- 객체에 바인딩된 함수(메서드)도 callable이며 constructor이기 때문에, 일반 함수로서 호출할 수도 있고, 생성자 함수로서 호출할 수도 있음 +- 객체에 바인딩된 함수가 constructor이라는 것은 객체에 바인딩된 함수가 prototype 프로퍼티를 가지며, 프로토타입 객체를 생성한다는 것을 의미 +- 콜백 함수도 constructor이기 때문에 불필요한 프로토타입 객체를 생성함 + + **😀 ES6 함수 구분** + +| ES6 함수의 구분 | constructor | prototype | super | arguments | +| --- | --- | --- | --- | --- | +| 일반 함수 | ⭕️ | ⭕️ | ❌ | ⭕️ | +| 메서드 | ❌ | ❌ | ⭕️ | ⭕️ | +| 화살표 함수 | ❌ | ❌ | ❌ | ❌ | + +## 26.2. 메서드 + +ES6에서의 메서드: **메서드 축약 표현으로 정의된 함수**만을 의미 + +```jsx +const obj = { + x: 1, + foo() { return this.x; }, // 메서드 + bar(): function (){ return this.x; } // 일반 함수 +} +``` + +- ES6에서 정의한 메서드는 인스턴스를 생성할 수 없는 non-constructor → 생성자 함수로서 호출 불가 + +```jsx +new obj.foo(); // typeError +new obj.bar(); // bar() +``` + +- ES6에서 정의한 메서드는 인스턴스를 생성할 수 없으므로, prototype 프로퍼티X, 프로토타입 생성 X +- 표준 빌드인 객체가 제공하는 프로토타입 메서드와 정적 메서드는 모두 non-constructor + +- ES6 메서드는 **자신을 바인딩한 객체**를 가리키는 내부 슬롯 **`[[HomeObject]]`**를 가짐 +- ES6 메서드는 `super` 키워드를 사용할 수 있음 + - `super` 참조는 내부 슬롯 **`[[HomeObject]]`**를 사용하여 수퍼클래스의 메서드를 참조하므로 + +```jsx +const base = { + name: 'Lee', + sayHi(){ + return `Hi! ${this.name}`; + } +}; + +const derived = { + __proto__: base, + + //sayHi는 ES6 메서드 + // sayHidml [[HomeObject]]는 sayHi가 바인딩된 객체인 derived를 가리킴 + // super는 sayHi의 [[HomeObject]]의 프로토타입인 base를 가리킴 + sayHi(){ + return `${super.sayHi()}. How are you doing?`; + } +} +``` + +- ES6 메서드가 아닌 함수는 super 키워드를 사용할 수 없음 + - 내부슬롯 [[HomeObject]]를 가지지 않기 때문 + +## 26.3. 화살표 함수 + +### 26.3.1. 화살표 함수 정의 + +- 함수 표현식으로 정의 + + ```jsx + const multi = (x, y) => x * y; + multi(2, 3); + ``` + +- 매개변수 선언 + + ```jsx + const arrow1 = (x, y) => { ... }; + const arrow2 = x => { ... }; // 매개변수 1개이면, 소괄호 생략 가능 + const arrow3 = () => { ... }; // 매개변수 0개이면, 소괄호 생략 불가 + ``` + +- 함수 몸체 정의 + - 함수 몸체가 하나의 문으로 구성된다면 중괄호 생략 가능 + - 함수 몸체 내부의 문이 값으로 평가될 수 있는 표현식인 문이라면 암묵적으로 반환 + + ```jsx + const power = x => x ** 2; + const power = x => { return x ** 2; }; // 상동 + ``` + + - 함수 몸체 내부의 문이 값으로 평가될 수 있는 표현식이 아닌 문인데 중괄호를 생략하면 에러 발생 → 중괄호 꼭 써야 함 + + ```jsx + const power = () => const x = 2; // SyntaxError + const power = () => { const x = 2; }; + ``` + + - 객체 리터럴을 반환하는 경우, 객체 리터럴을 소괄호로 감싸주어야 + + ```jsx + const create = (id, content) => ({ id, content }); + ``` + + - 객체 리터럴을 소괄호로 감싸지 않으면, 중괄호를 함수 몸체를 감싸는 중괄호로 잘못 해석함 + + ```jsx + const create = (id, content) => { id, content }; + create(1, 'hello'); // undefined + ``` + + - 화살표 함수도 즉시 실행함수 IIFE로 사용 가능 + + ```jsx + const person = ( name => ({ + sayHi() { return `Hi? My name is ${name}`}; } + }))('Lee';) + ``` + + - 화살표 함수도 일급 객체이므로 고차함수에 인수로 전달할 수도 있음 + +### 26.3.2. 화살표 함수와 일반 함수의 차이 + +1. 화살표 함수는 인스턴스를 생성할 수 없는 non-constructor + + ```jsx + const Foo = () => {}; + new Foo(); // TypeError + ``` + +2. 중복된 매개변수 이름을 선언할 수 없음 + + ```jsx + const arrow = (a, a) => a + a; // SyntaxError + ``` + +3. 화살표 함수는 함수 자체의 `this, arguments, super, [new.target](http://new.target)` 바인딩을 갖지 않음 + 1. 화살표 함수 내부에서 `this, arguments, super, [new.target](http://new.target)`를 참조하면 스코프 체이닝을 통해서 상위 스코프의 `this, arguments, super, [new.target](http://new.target)`를 참조함 + 2. 그 상위 스코프에서도 화살표 함수라면 가장 가까운 상위 함수 중에서 화살표 함수가 아닌 함수의 `this, arguments, super, [new.target](http://new.target)`를 참조 + +### 26.3.3. `this` + +`this` 바인딩은 함수의 **호출** 방식에 의해 동적으로 결정됨 + +일반 함수로서 호출되는 모든 함수 내부의 `this`는 전역 객체를 가리킴 + +화살표 함수를 사용하여 “콜백 함수 내부의 this(가 전역 객체를 가리켜서 원하는 this를 못 부르는 )문제”를 해결할 수 있음 + +화살표 함수는 함수 자체의 `this` 바인딩을 갖지 않음 + +**→ 화살표 함수 내부에서 this를 참조하면 상위 스코프의 this를 그대로 참조함(Lexical This)** + +→ `Function.prototype.call`, `Function.prototype.apply`, `Function.prototype.bind` 메서드를 사용해도 화살표 함수 내부의 this를 교체할 수 없음 + +→ this를 교체할 수 없고, 언제나 상위 스코프의 `this` 바인딩을 참조함 + +### 26.3.4. super + +화살표 함수는 함수 자체의 `super` 바인딩을 갖지 않음 + +→ 화살표 함수 내부에서 `super`를 참조하면 상위 스코프의 `super`를 그대로 참조함 + +### 26.3.5. arguments + +화살표 함수는 함수 자체의 `arguments` 바인딩을 갖지 않음 + +→ 화살표 함수 내부에서 `arguments`를 참조하면 상위 스코프의 `arguments`를 그대로 참조함 + +→ 화살표 함수로 가변 인자 함수를 구현할 때는 `Rest` 파라미터를 반드시 사용 + +## 26.4. Rest 파라미터 + +- Rest 파라미터는 함수에 전달된 인수들의 목록을 배열로 전달받음 +- 일반 매개변수와 Rest 파라미터는 함께 사용할 수 있다. 함수에 전달된 인수들은 매개변수와 Rest 파라 미터에 순차적으로 할당됨 +- Rest 파라미터는 반드시 마지막 파라미터이어야 + +- arguments 객체는 배열이 아닌 유사 배열 객체이므로 배열 메서드를 사용하려면 Function. +prototype.call이나 Function.prototype.apply 메서드를 사용해 arguments 객체를 배열로 변환해야 +- ES6에서는 rest 파라미터를 사용하여 가변 인자 함수의 인수 목록을 배열로 직접 전달받을 수 있다. +- 화살표 함수로 가변 인자 함수를 구현해야 할 때는 반드시 Rest 파라미터를 사용해야 + +## 26.5. 매개변수 기본값 + +ES6에서 도입된 매개변수 기본값을 사용하면 함수 내에서 수행하던 인수 체크 및 초기화를 간소화할 수 있다. + +```tsx +function sum (x = 0, y = 0) [ + return x + y; +} +``` + +매개변수에 인수를 전달하지 않은 경우와 undefined를 전달한 경우에만 + +# 27장 배열 + +## **27.1. 배열?** + +여러 개의 값을 순차적으로 나열한 자료구조 + +**length 프로퍼티** → for문으로 접근 가능 + +javascript에서 배열은 객체 타입 + +| 구분 | 객체 | 배열 | +| --- | --- | --- | +| 구조 | 프로퍼티 키와 프로퍼티 값 | 인덱스와 요소 | +| 값의 참조 | 프로퍼티 키 | 인덱스 | +| 값의 순서 | X | O | +| length프로퍼티 | X | O | + +## **27.2. 자바스크립트 배열은 배열이 아니다** + + + +희소 배열: 배열의 요소가 연속적으로 이어져 있지 않는 배열 + +자바스크립트 배열은 + +- 인덱스를 나타내는 문자열을 프로퍼티로 가지며, length 프로퍼티를 갖는 특수한 객체 +- 요소는 사실 프로퍼티 값 +- 인덱스로 배열 요소에 접근하는 경우에는 일반적인 배열보다 느리지만 특정 요소를 검색하거나 요소를 삽입 또는 삭제하는 경우에는 일반적인 배열보다 빠름 + + + +## **27.3. length 프로퍼티와 희소 배열** + +- length 프로퍼티 값은 요소를 추가/삭제할 때 자동 갱신 +- 임의의 숫자를 명시적으로 할당할 수 있음 +- 배열 길이보다 작은 값을 지정하면 배열의 길이가 줄어든다. +- 배열 길이보다 큰 값을 할당하면 length에는 반영되지만 실제 배열 길이가 늘어나지는 않음 + +- 희소 배열은 length와 배열 요소의 개수가 일치하지 않음 +- 희소 배열의 length는 희소 배열의 실제 요소 개수보다 언제나 큼 + + + + 배열에는 같은 타입 요소를 연속적으로 위치시키는 것이 최선 + +## **27.4. 배열 생성** + +### 27.4.1. 배열 리터럴 + +```tsx +const arr = []; +const arr = [1, 2, 3]; +const arr = [1, , 3]; // 희소 배열 +``` + +### 27.4.2. Array 생성자 함수 + +```tsx +const arr = new Array(10); // length가 10인 배열 생성 +const arr = new Array(); +const arr = new Array(1, 2, 3); +const arr = new Array({}); +``` + +`Array` 생성자 함수는 `new` 연산자와 함께 호출하지 않더라도, 배열 생성자 함수로 동작함 + +→ `Array` 생성자 함수 내부에서 `new.target`을 확인하기 때문 + +```tsx +const arr = Array(1, 2, 3); +``` + +### 27.4.3. Array.of + +```tsx +Array.of(1); // [1] +Array.of(1, 2, 3); +Array.of('string'); +``` + +### 27.4.4. Array.from + +```tsx +Array.from({length: 2, 0: 'a', 1: 'b'}); // ['a', 'b'] +Array.from('hello'); // ['h','e','l','l','o'] +``` + +## **27.5. 배열 요소의 참조** + +배열의 요소를 참조할 때에는 `[]` 표기법을 사용 + +```tsx +const arr = [1. 2]; +console.log(arr[0]); // 1 +``` + + **존재하지 않는 요소에 대해서는 `undefined` 를 리턴** + +## **27.6. 배열요소의 추가와 갱신** + +존재하지 않는 인덱스를 사용하여 값을 할당하면 새로운 요소가 추가됨 → `length` 는 자동 갱신 + +이미 존재하는 요소에 값을 재할당하면 요소 값이 갱신됨 + +## **27.7. 배열 요소의 삭제** + +`delete` 연산자 사용 가능하지만 쓰지말기 → 희소 배열됨 + +`Array.prototype.splice` 메서드로 삭제하셈 + +## **27.8. 배열 메서드** + +원본 배열을 직접 변경하는 메서드 / 원본 배열을 직접 변경하지 않고 새로운 배열을 생성하여 반환하는 메서드 + +### 27.8.1. Array.isArray + +전달된 인수가 배열이면 true, 배열이 아니면 false + +### 27.8.2. Array.prototype.indexOf + +원본배열에서 전달된 요소의 인덱스 반환 + +### 27.8.3. Array.prototype.push + +인수 모든 값을 원본 배열의 마지막 요소로 추가하고 변경된 length프로퍼티 값을 반환 + +원본 배열을 직접 변경 + +`push`보다는 스프레드 문법을 사용할 것 + +### 27.8.4. Array.prototype.pop + +원본 배열에서 마지막 요소를 제거하고, 제거한 요소를 반환 + +원본 배열이 빈 배열이면 `undefined` 반환 + +원본 배열을 직접 변경 + +### 27.8.5. Array.prototype.unshift + +인수의 값을 원본 배열의 선두에 요소로 추가하고 변경된 length프로퍼티 값을 반환 + +원본 배열을 직접 변경 + +`unshift`보다는 스프레드 문법을 사용할 것 + +### 27.8.6. Array.prototype.shift + +원본 배열에서 첫 번째 요소를 제거하고 제거한 요소를 반환 + +빈 배열이면 `undefined` 반환 + +원본 배열을 직접 변경 + +### 27.8.7. Array.prototype.concat + +인수로 전달된 값들을 원본 배열의 마지막 요소로 추가한 **새로운 배열**을 반환 + +인수가 배열인 경우, 배열을 해체하여 새로운 배열의 요소로 추가함 + +스프레드 문법으로 대체 가능 + +### 27.8.8. Array.prototype.splice + +원본 배열의 중간에 요소를 추가하거나 제거함 + +```tsx +arr.splice(start, deleteCount, ?items) +``` + +원본 배열을 직접 변경 + +### 27.8.9. Array.prototype.slice + +인수로 전달된 범위의 요소들을 복사하여 배열로 반환 + +```tsx +arr.slice(start, end); +``` + +### 27.8.10. Array.prototype.join + +원본 배열의 모든 요소를 문자열로 변환한 후, 인수로 전달받은 구분자로 연결한 문자열을 반환함 + +기본 구문자 - `,` + +### 27.8.11. Array.prototype.reverse + +원본 배열의 순서를 반대로 뒤집음 + +원본 배열을 직접 변경 + +### 27.8.12. Array.prototype.fill + +인수로 전달받은 값을 배열의 처음부터 끝까지 요소로 채움 + +원본 배열을 직접 변경 + +### 27.8.13. Array.prototype.includes + +배열 내에 특정 요소가 포함되어 있는지를 확인하여 true, false를 반환 + +### 27.8.14. Array.prototype.flat + +인수로 전달한 깊이만큼 재귀적으로 배열을 평탄화 + +## 27.9. 배열 고차 함수 + +고차 함수 : 함수를 인수로 전달받거나 함수를 반환하는 함수 + +함수형 프로그래밍: 조건문과 반복문을 제거하여 복잡성을 해결하고, 변수의 사용을 억제하여 상태 변경을 피하려는 프로그래밍 패러다임 + +→ 순수함수를 통해 부수 효과를 최대한 억제하여 오류를 피하고자 함 + +### 27.9.1 Array.prototype.sort + +배열의 요소를 정렬 + +원본 배열을 직접 변경하여 정렬된 배열을 반환 + +- 유니코드 코드 포인트의 순서로 기본 정렬됨 + +```tsx +points.sort((a, b) => a - b); // 이렇게 해야 숫자 오름차순이 됨 +``` + +### 27.9.2 Array.prototype.forEach + +for문을 대체하는 고차함수 + +**내부에서 반복문을 통해 자신을 호출한 배열을 순회하면서 수행해야 할 처리를 콜백함수로 전달받아 반복 호출함** + +- 폴리필 : 브라우저에서 지원하지 않는 코드를 사용 가능한 코드 조각이나 플러그인으로 변환환 코드 + + ```tsx + // 만약 Array.prototype.forEach가 존재하지 않으면 폴리필 추가 + if(!Array.prototype.forEach){ + Array.prototype.forEach = function (callback, thisArg) { + // 첫번째 인수가 함수가 아니면 typeError 발생 + if (typeof callback !== 'function') { + throw new TypeError(callback + 'is not a function'); + } + // this로 사용할 두번째 인수를 전달받지 못하면 전역 객체를 this로 사용함 + thisArg = thisArg || window; + for (var i = 0; i < this.length; i++){ + // call 메서드를 통해 thisArg 를 전달하면서 콜백함수를 호출함 + // 이때 콜백 함수의 인수로 배열 요소, 인덱스, 배열 자신을 전달함 + callback.call(thisArg, this[i], i, this); + } + } + } + ``` + + +### 27.9.3 Array.prototype.map + +자신을 호출한 배열의 모든 요소를 순회하면서 인수로 전달받은 콜백 함수를 반복 호출 + +**콜백 함수의 반환값들로 구성된 새로운 배열을 반환** + +### 27.9.4 Array.prototype.filter + +콜백 함수의 반환값이 true인 요소로만 구성된 새로운 배열을 반환 + +### 27.9.5 Array.prototype.reduce + +모든 요소를 순회하면서, 하나의 결과값을 만들어 반환 + +```tsx +const sum = [1, 2, 3, 4].reduce((accumulator, currentValue, index, array) => accumulator + currentValue, 0) +``` + +| 구분 | accumulator | currentValue | index | array | 결과 함수의 반환값 | +| --- | --- | --- | --- | --- | --- | +| 첫 번째 순회 | 0 (초기값) | 1 | 0 | [1, 2, 3, 4] | 1 (accumulator + currentValue) | +| 두 번째 순회 | 1 | 2 | 1 | [1, 2, 3, 4] | 3 (accumulator + currentValue) | +| 세 번째 순회 | 3 | 3 | 2 | [1, 2, 3, 4] | 6 (accumulator + currentValue) | +| 네 번째 순회 | 6 | 4 | 3 | [1, 2, 3, 4] | 10 (accumulator + currentValue) | + +### 27.9.6 Array.prototype.some + +배열의 요소를 순회하며, 콜백 함수의 값이 단 한 번이라도 참이면 true, 아니면 false + +### 27.9.7 Array.prototype.every + +배열의 요소를 순회하며, 콜백 함수의 값이 모두 참이면 true, 하나라도 아니면 false + +### 27.9.8 Array.prototype.find + +콜백 함수의 반환값이 true 인 첫 번째 요소를 반환 + +### 27.9.9 Array.prototype.findIndex + +콜백 함수의 반환값이 true 인 첫 번째 요소의 index를 반환 + +### 27.9.10 Array.prototype.flatMap + +`map` 메서드를 통해 생성된 배열을 평탄화 → `map` 메서드와 `flat` 메서드를 순차적으로 실행하는 효과 + +# 28장 Number + +표준 빌트인 객체 Number는 숫자를 다루는 프로퍼티와 메서드를 제공 + +## 28.1. Number 생성자 함수 + +- 인수 전달하지 않고 new 연산자와 호출하면 0을 할당한 래퍼 객체 +- new 연산자 없이 호출하면 숫자를 반환 + +```tsx +const numObj = new Number(); +console.log(numObj); // Number {[[PrimitiveValue]]: 0} +``` + +## 28.2. Number 프로퍼티 + +- Number.EPSILON + - 부동소수점으로 인해 발생하는 오차를 해결하기 위해 사용 +- Number.MAX_VALUE + - Number MAX_VALUE보다 큰 숫자는 Infinity +- Number.MIN_VALUE + - Number MIN_VALUE보다 작은 숫자는 0 +- Number.MAX_SAFE_INTEGER + - 자바스크립트에서 안전하게 표현할 수 있는 가장 큰 정수값 +- Number.MIN_SAFE_INTEGER + - 자바스크립트에서 안전하게 표현할 수 있는 가장 작은 정수값 +- Number.POSITIVE_INFINITY + - == Infinity +- Number.NEGATIVE_INFINITY + - == -Infinity +- Number.NaN + +## 28.3. Number 메서드 + +- Number.isFinite + - 인수로 전달된 숫자값이 정상적인 유한수, 즉 Infinity 또 는 -Infinity가 아닌지 검사하여 true/false 리턴 + - 숫자가 아닌 반환값이 오면 false +- Number.isInteger + - 인수로 전달된 숫자값이 정수인지 검사하여 true/false 리턴 + - 인수를 숫자로 암묵적 타입 변환X +- Number.isNaN + - 숫자가 아닌 반환값이 오면 false +- Number.isSafeInteger + - 숫자값이 안전한 정수인지 검사 +- Number.prototvpe.toExponential + - 숫자를 지수 표기법으로 변환하여 문자열로 반환 +- Number.prototype.toFixed + - 숫자를 반올림하여 **문자열**로 반환 +- Number.prototype.toPrecision + - 전체 자릿수까지 유효하도록 나머지 자릿수를 반올림하여 문자열로 반환 +- Number.prototype.toString + - 숫자를 문자열로 변환하여 반환