Skip to content

Commit bb3f0da

Browse files
authored
Update chapter_26.md
1 parent 3e203b2 commit bb3f0da

File tree

1 file changed

+70
-15
lines changed

1 file changed

+70
-15
lines changed

book/공희재/chapter_26.md

Lines changed: 70 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Chapter 26 - ES6 함수의 추가 기능
22
## 1. 함수의 구분
3-
ES6 이전까지 자바스크립트의 함수는 별다른 구분 없이 다양한 목적으로 사용되었다. 이는 편리한 것 같지만 실수를 유발시킬 수 있으며 성능 면에서도 손해다. 예제를 살펴 보자.
3+
ES6 이전까지 자바스크립트의 함수는 별다른 구분 없이 다양한 목적으로 사용되었다.<br/>
4+
이는 편리한 것 같지만 실수를 유발시킬 수 있으며 성능 면에서도 손해다. 예제를 살펴 보자.
45
```javascript
56
var foo = function() {
67
return 1;
@@ -17,9 +18,11 @@ var obj = { foo: foo };
1718
obj.foo(); // -> 1
1819
```
1920

20-
ES6 이전의 모든 함수는 사용 목적에 따라 명확한 구분이 없으므로 호출 방식에 특별한 제약이 없고 생성자 함수로 호출되지 않아도 프로토타입 객체를 생성한다. 이는 혼란스러우며 실수를 유발할 가능성이 있고, 성능에도 좋지 않다.
21+
ES6 이전의 모든 함수는 사용 목적에 따라 명확한 구분이 없으므로<br/>
22+
호출 방식에 특별한 제약이 없고 생성자 함수로 호출되지 않아도 프로토타입 객체를 생성한다.<br/>
23+
자바스크립트 함수의 이러한 특징은 이해하기 혼란스럽고, 프로그램 성능에도 좋지 않다.
2124

22-
이러한 문제를 해결하기 위해, ES6에서는 함수를 사용 목적에 따라 세 가지 종류로 구분해 정의했다.
25+
이러한 문제를 해결하기 위해, **ES6에서는 함수를 사용 목적에 따라 세 가지 종류로 구분** 정의했다.
2326

2427
|**ES6 함수의 구분**|`constructor`|`prototype`|`super`|`arguments`|
2528
|-|-|-|-|-|
@@ -30,7 +33,7 @@ ES6 이전의 모든 함수는 사용 목적에 따라 명확한 구분이 없
3033
일반 함수는 constructor이지만, ES6의 메서드와 화살표 함수는 non-constructor이다. 다음 절에서 더 자세히 살펴 보자.
3134

3235
## 2. ES6 Methods: 메서드
33-
ES6 사양에서는 메서드에 대한 정의가 명확하게 규정되었다: 메서드 축약 표현으로 정의된 함수만이 메서드다.
36+
ES6 사양에서는 메서드에 대한 정의가 명확하게 규정되었다: **메서드 축약 표현으로 정의된 함수만이 '메서드'다.**
3437
```javascript
3538
const obj = {
3639
x: 1,
@@ -39,27 +42,33 @@ const obj = {
3942
};
4043
```
4144

42-
ES6에서 정의한 '메서드'는, 인스턴스를 생성할 수 없는 non-constructor이다. 따라서 생성자 함수로서 호출할 수 없게 된다. ES6 메서드는 인스턴스를 생성할 수 없으므로 prototype 프로퍼티가 없고 프로토타입도 생성하지 않는다.
43-
45+
ES6에서 정의한 '**메서드**'는, 인스턴스를 생성할 수 없는 non-constructor이다. 따라서 생성자 함수로서 호출할 수 없게 된다.<br/>
46+
ES6 메서드는 인스턴스를 생성할 수 없으므로 prototype 프로퍼티가 없고 프로토타입도 생성하지 않는다.<br/>
4447
또한, ES6 메서드는 자신을 바인딩한 객체를 가리키는 슬롯 `[[HomeObject]]`를 갖기 때문에, `super` 키워드를 사용할 수 있다.
4548

4649
이처럼 ES6 메서드는 본연의 기능인 `super`를 추가하고, 의미적으로 맞지 않는 기능인 constructor는 제거했다.
4750

4851
## 3. Arrow Functions: 화살표 함수
49-
화살표 함수는, 표현만 간략한 게 아니라 내부 동작도 기존 함수의 동작보다 간략하다. 특히, 화살표 함수는 콜백 함수 내부에서 `this`가 전역 객체를 가리키는 문제를 해결하기 위한 대안으로 유용하다.
52+
화살표 함수는, 기존의 함수와 비교해 표현만 간략한 게 아니라 **내부 동작도 간략**하다.<br/>
53+
특히, 화살표 함수는 콜백 함수 내부에서 **`this`가 전역 객체를 가리키는 문제를 해결**한다.
5054

5155
### 3-1. 화살표 함수 정의
5256
생략. 책을 참고합시다~
5357

5458
### 3-2. 화살표 함수와 일반 함수의 차이
55-
1. 화살표 함수는 인스턴스를 생성할 수 없는 non-constructor이다.
59+
1. 화살표 함수는 인스턴스를 생성할 수 없는 **non-constructor**이다.
5660
2. 화살표 함수는 중복된 매개변수 이름을 선언할 수 없다.
57-
3. 화살표 함수는 함수 자체의 `this`, `arguments`, `super`, `new.target` 바인딩을 갖지 않는다.
61+
3. 화살표 함수는 함수 자체의 `this`, `arguments`, `super`, `new.target` 바인딩을 **갖지 않는다**.
5862

5963
### 3-3. `this`
60-
화살표 함수의 `this`는 일반 함수의 그것과 다르게 동작한다. 화살표 함수의 `this`가 다르게 동작하는 것은 의도된 설계다: 콜백 함수 내부의 `this`가, 외부 함수의 `this`와 달라 혼란을 발생시키는 문제를 해결하기 위함이다.
61-
62-
22장에서 배웠듯이 `this`의 값은 함수가 어떻게 호출됐는지에 따라 다르게 바인딩된다. 자바스크립트의 이러한 특징은, 콜백 함수를 일반 함수 형태로 호출할 때 골치 아파진다. 일반 함수로 호출하는 모든 함수의 내부에는 `this`가 전역 객체를 가리키지만, 그 함수가 만약 클래스 내부라면 `undefined`를 바인딩하게 된다. 클래스 내부의 모든 코드에는 strict mode가 적용되는 영향을 받기 때문이다.
64+
화살표 함수의 `this`는 일반 함수의 그것과 다르게 동작한다. 이건 의도된 설계다:<br/>
65+
**콜백 함수 내부의 `this`가, 외부 함수의 `this`와 달라 혼란을 발생시키는 문제를 해결하기 위함**이다.
66+
67+
22장에서 배웠듯이 `this`의 값은 함수가 어떻게 호출됐는지에 따라 다르게 바인딩된다.<br/>
68+
자바스크립트의 이러한 특징은, **콜백 함수를 일반 함수 형태로 호출할 때 골치 아파진다**.<br/>
69+
일반 함수로 호출하는 모든 함수의 내부에는 `this`가 전역 객체를 가리키지만,<br/>
70+
그 함수가 만약 클래스 내부라면 `undefined`를 바인딩하게 된다.<br/>
71+
클래스 내부의 모든 코드에는 strict mode가 적용되는 영향을 받기 때문이다.
6372
```javascript
6473
// ❌ Wrong Practice!! ❌
6574
class Prefixer {
@@ -75,7 +84,8 @@ class Prefixer {
7584
}
7685
```
7786

78-
이런 문제를 우리는 **콜백 함수 내부의 `this` 문제**라고 부른다. ES6에서는, 콜백 함수 내부의 `this` 문제를 해결하기 위해 화살표 함수를 제안한다.
87+
이런 문제를 우리는 **콜백 함수 내부의 `this` 문제**라고 부른다.<br/>
88+
ES6에서는, 콜백 함수 내부의 `this` 문제를 해결하기 위해 화살표 함수를 제안한다.
7989

8090
```javascript
8191
// ✅ 위 예제를 화살표 함수로 해결 ✅
@@ -90,7 +100,11 @@ class Prefixer {
90100
}
91101
```
92102

93-
화살표 함수는 함수 자체의 `this` 바인딩을 갖지 않는다. 따라서 화살표 함수 내부에서 `this`를 참조하면 상위 스코프의 `this`를 그대로 참조한다. 우리는 이를 **Lexical This**라고 부른다. Lexical this는 마치 렉시컬 스코프처럼, 화살표 함수의 `this`는 함수가 정의된 위치에 의해 결정되는 `this`임을 의미한다.
103+
화살표 함수는 함수 자체의 `this` 바인딩을 갖지 않는다.<br/>
104+
따라서 **화살표 함수 내부에서 `this`를 참조하면 상위 스코프의 `this`를 그대로 참조**한다.
105+
106+
우리는 이를 **Lexical This**라고 부른다.<br/>
107+
Lexical this는 마치 렉시컬 스코프처럼, 화살표 함수의 `this`**함수가 정의된 위치에 의해 결정**되는 `this`임을 의미한다.
94108

95109
한 가지 유의할 점은 객체 내 메서드를 정의할 땐 화살표 함수를 사용하지 않아야 한다는 점이다.
96110
```javascript
@@ -100,7 +114,8 @@ const person = {
100114
sayHi: () => console.log(`hey ${this.name}`)
101115
};
102116
```
103-
위 예제가 틀린 이유는, sayHi 프로퍼티에 할당한 화살표 함수의 `this`는, 메서드를 호출한 객체인 person을 가리키는 게 아니라, 상위 스코프인 전역 객체를 가리키기 때문이다.
117+
위 예제가 틀린 이유는, sayHi 프로퍼티에 할당한 화살표 함수의 `this`는,<br/>
118+
메서드를 호출한 객체인 person을 가리키는 게 아니라, 상위 스코프인 전역 객체를 가리키기 때문이다.
104119

105120
따라서 **객체의 메서드를 정의할 땐** 아래처럼 ES6 메서드 축약 표현으로 정의한 **ES6 메서드**를 사용하는 것이 좋다.
106121
```javascript
@@ -114,11 +129,51 @@ const person = {
114129
```
115130

116131
### 3-4. `super`
132+
화살표 함수는 함수 자체의 super 바인딩을 갖지 않는다.<br/>
133+
따라서 화살표 함수 안에서 `super`를 참조하면, `this`가 동작하는 것과 마찬가지로 상위 스코프의 `super`를 참조한다.
134+
```javascript
135+
class Base {
136+
constructor(name) {
137+
this.name = name;
138+
}
139+
140+
sayHi() {
141+
return `Hi! ${this.name}`;
142+
}
143+
}
144+
145+
class Derived extends Base {
146+
sayHi = () => `${super.sayHi()} how are you doing?`;
147+
}
148+
149+
const derived = new Derived('Lee');
150+
console.log(derived.sayHi()); // Hi! Lee how are you doing?
151+
```
152+
117153
### 3-5. `arguments`
154+
마찬가지로 화살표 함수는 함수 자체의 arguments 바인딩을 갖지 않는다.<br/>
155+
따라서 화살표 함수 안에서 `arguments`를 참조하면, `this`가 동작하는 것과 마찬가지로 상위 스코프의 `arguments`를 참조한다.
156+
157+
이처럼 **화살표 함수에서 가변 인자 함수**를 구현해야 할 때는<br/>
158+
(`arguments`를 쓰지 못하므로) 반드시 **Rest 파라미터**를 사용해야 한다.
118159

119160
## 4. Rest 파라미터
120161
### 4-1. 기본 문법
162+
Rest 파라미터는 아래처럼 함수에 전달된 인수들의 목록을 **배열**로 받는다.<br/>
163+
Rest 파라미터는 단 하나만 선언할 수 있으며, 다른 일반 매개변수와 섞어 쓸 수 있다.
164+
```javascript
165+
function foo(param, ...rest) {
166+
console.log(param); // 1
167+
console.log(rest); // [2, 3, 4, 5]
168+
}
169+
170+
foo(1, 2, 3, 4, 5);
171+
```
172+
121173
### 4-2. Rest 파라미터와 `arguments` 객체
174+
Rest 파라미터와 `arguments` 객체 간 가장 큰 차이점은 바로 배열이냐 아니냐에 있다.<br/>
175+
`arguments` 객체는 유사 배열 객체이므로 반드시 배열로 변환해야만 배열 메서드를 사용할 수 있는 반면,<br/>
176+
**Rest 파라미터는 배열**이므로 `map`이나 `filter` 같은 배열 메서드를 곧바로 사용할 수 있다.
122177

123178
## 5. 매개변수 기본값
124179
생략. 책을 참고합시다~!

0 commit comments

Comments
 (0)