You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: book/공희재/chapter_26.md
+70-15Lines changed: 70 additions & 15 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,7 @@
1
1
# Chapter 26 - ES6 함수의 추가 기능
2
2
## 1. 함수의 구분
3
-
ES6 이전까지 자바스크립트의 함수는 별다른 구분 없이 다양한 목적으로 사용되었다. 이는 편리한 것 같지만 실수를 유발시킬 수 있으며 성능 면에서도 손해다. 예제를 살펴 보자.
3
+
ES6 이전까지 자바스크립트의 함수는 별다른 구분 없이 다양한 목적으로 사용되었다.<br/>
4
+
이는 편리한 것 같지만 실수를 유발시킬 수 있으며 성능 면에서도 손해다. 예제를 살펴 보자.
4
5
```javascript
5
6
varfoo=function() {
6
7
return1;
@@ -17,9 +18,11 @@ var obj = { foo: foo };
17
18
obj.foo(); // -> 1
18
19
```
19
20
20
-
ES6 이전의 모든 함수는 사용 목적에 따라 명확한 구분이 없으므로 호출 방식에 특별한 제약이 없고 생성자 함수로 호출되지 않아도 프로토타입 객체를 생성한다. 이는 혼란스러우며 실수를 유발할 가능성이 있고, 성능에도 좋지 않다.
21
+
ES6 이전의 모든 함수는 사용 목적에 따라 명확한 구분이 없으므로<br/>
22
+
호출 방식에 특별한 제약이 없고 생성자 함수로 호출되지 않아도 프로토타입 객체를 생성한다.<br/>
23
+
자바스크립트 함수의 이러한 특징은 이해하기 혼란스럽고, 프로그램 성능에도 좋지 않다.
21
24
22
-
이러한 문제를 해결하기 위해, ES6에서는 함수를 사용 목적에 따라 세 가지 종류로 구분해 정의했다.
25
+
이러한 문제를 해결하기 위해, **ES6에서는 함수를 사용 목적에 따라 세 가지 종류로 구분**해 정의했다.
23
26
24
27
|**ES6 함수의 구분**|`constructor`|`prototype`|`super`|`arguments`|
25
28
|-|-|-|-|-|
@@ -30,7 +33,7 @@ ES6 이전의 모든 함수는 사용 목적에 따라 명확한 구분이 없
30
33
일반 함수는 constructor이지만, ES6의 메서드와 화살표 함수는 non-constructor이다. 다음 절에서 더 자세히 살펴 보자.
31
34
32
35
## 2. ES6 Methods: 메서드
33
-
ES6 사양에서는 메서드에 대한 정의가 명확하게 규정되었다: 메서드 축약 표현으로 정의된 함수만이 메서드다.
36
+
ES6 사양에서는 메서드에 대한 정의가 명확하게 규정되었다: **메서드 축약 표현으로 정의된 함수만이 '메서드'다.**
34
37
```javascript
35
38
constobj= {
36
39
x:1,
@@ -39,27 +42,33 @@ const obj = {
39
42
};
40
43
```
41
44
42
-
ES6에서 정의한 '메서드'는, 인스턴스를 생성할 수 없는 non-constructor이다. 따라서 생성자 함수로서 호출할 수 없게 된다. ES6 메서드는 인스턴스를 생성할 수 없으므로 prototype 프로퍼티가 없고 프로토타입도 생성하지 않는다.
43
-
45
+
ES6에서 정의한 '**메서드**'는, 인스턴스를 생성할 수 없는 non-constructor이다. 따라서 생성자 함수로서 호출할 수 없게 된다.<br/>
46
+
ES6 메서드는 인스턴스를 생성할 수 없으므로 prototype 프로퍼티가 없고 프로토타입도 생성하지 않는다.<br/>
44
47
또한, ES6 메서드는 자신을 바인딩한 객체를 가리키는 슬롯 `[[HomeObject]]`를 갖기 때문에, `super` 키워드를 사용할 수 있다.
45
48
46
49
이처럼 ES6 메서드는 본연의 기능인 `super`를 추가하고, 의미적으로 맞지 않는 기능인 constructor는 제거했다.
47
50
48
51
## 3. Arrow Functions: 화살표 함수
49
-
화살표 함수는, 표현만 간략한 게 아니라 내부 동작도 기존 함수의 동작보다 간략하다. 특히, 화살표 함수는 콜백 함수 내부에서 `this`가 전역 객체를 가리키는 문제를 해결하기 위한 대안으로 유용하다.
52
+
화살표 함수는, 기존의 함수와 비교해 표현만 간략한 게 아니라 **내부 동작도 간략**하다.<br/>
53
+
특히, 화살표 함수는 콜백 함수 내부에서 **`this`가 전역 객체를 가리키는 문제를 해결**한다.
50
54
51
55
### 3-1. 화살표 함수 정의
52
56
생략. 책을 참고합시다~
53
57
54
58
### 3-2. 화살표 함수와 일반 함수의 차이
55
-
1. 화살표 함수는 인스턴스를 생성할 수 없는 non-constructor이다.
59
+
1. 화살표 함수는 인스턴스를 생성할 수 없는 **non-constructor**이다.
56
60
2. 화살표 함수는 중복된 매개변수 이름을 선언할 수 없다.
57
-
3. 화살표 함수는 함수 자체의 `this`, `arguments`, `super`, `new.target` 바인딩을 갖지 않는다.
61
+
3. 화살표 함수는 함수 자체의 `this`, `arguments`, `super`, `new.target` 바인딩을 **갖지 않는다**.
58
62
59
63
### 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가 적용되는 영향을 받기 때문이다.
63
72
```javascript
64
73
// ❌ Wrong Practice!! ❌
65
74
classPrefixer {
@@ -75,7 +84,8 @@ class Prefixer {
75
84
}
76
85
```
77
86
78
-
이런 문제를 우리는 **콜백 함수 내부의 `this` 문제**라고 부른다. ES6에서는, 콜백 함수 내부의 `this` 문제를 해결하기 위해 화살표 함수를 제안한다.
87
+
이런 문제를 우리는 **콜백 함수 내부의 `this` 문제**라고 부른다.<br/>
88
+
ES6에서는, 콜백 함수 내부의 `this` 문제를 해결하기 위해 화살표 함수를 제안한다.
79
89
80
90
```javascript
81
91
// ✅ 위 예제를 화살표 함수로 해결 ✅
@@ -90,7 +100,11 @@ class Prefixer {
90
100
}
91
101
```
92
102
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`임을 의미한다.
94
108
95
109
한 가지 유의할 점은 객체 내 메서드를 정의할 땐 화살표 함수를 사용하지 않아야 한다는 점이다.
96
110
```javascript
@@ -100,7 +114,8 @@ const person = {
100
114
sayHi: () =>console.log(`hey ${this.name}`)
101
115
};
102
116
```
103
-
위 예제가 틀린 이유는, sayHi 프로퍼티에 할당한 화살표 함수의 `this`는, 메서드를 호출한 객체인 person을 가리키는 게 아니라, 상위 스코프인 전역 객체를 가리키기 때문이다.
117
+
위 예제가 틀린 이유는, sayHi 프로퍼티에 할당한 화살표 함수의 `this`는,<br/>
118
+
메서드를 호출한 객체인 person을 가리키는 게 아니라, 상위 스코프인 전역 객체를 가리키기 때문이다.
104
119
105
120
따라서 **객체의 메서드를 정의할 땐** 아래처럼 ES6 메서드 축약 표현으로 정의한 **ES6 메서드**를 사용하는 것이 좋다.
106
121
```javascript
@@ -114,11 +129,51 @@ const person = {
114
129
```
115
130
116
131
### 3-4. `super`
132
+
화살표 함수는 함수 자체의 super 바인딩을 갖지 않는다.<br/>
133
+
따라서 화살표 함수 안에서 `super`를 참조하면, `this`가 동작하는 것과 마찬가지로 상위 스코프의 `super`를 참조한다.
134
+
```javascript
135
+
classBase {
136
+
constructor(name) {
137
+
this.name= name;
138
+
}
139
+
140
+
sayHi() {
141
+
return`Hi! ${this.name}`;
142
+
}
143
+
}
144
+
145
+
classDerivedextendsBase {
146
+
sayHi= () =>`${super.sayHi()} how are you doing?`;
147
+
}
148
+
149
+
constderived=newDerived('Lee');
150
+
console.log(derived.sayHi()); // Hi! Lee how are you doing?
151
+
```
152
+
117
153
### 3-5. `arguments`
154
+
마찬가지로 화살표 함수는 함수 자체의 arguments 바인딩을 갖지 않는다.<br/>
155
+
따라서 화살표 함수 안에서 `arguments`를 참조하면, `this`가 동작하는 것과 마찬가지로 상위 스코프의 `arguments`를 참조한다.
156
+
157
+
이처럼 **화살표 함수에서 가변 인자 함수**를 구현해야 할 때는<br/>
158
+
(`arguments`를 쓰지 못하므로) 반드시 **Rest 파라미터**를 사용해야 한다.
118
159
119
160
## 4. Rest 파라미터
120
161
### 4-1. 기본 문법
162
+
Rest 파라미터는 아래처럼 함수에 전달된 인수들의 목록을 **배열**로 받는다.<br/>
163
+
Rest 파라미터는 단 하나만 선언할 수 있으며, 다른 일반 매개변수와 섞어 쓸 수 있다.
164
+
```javascript
165
+
functionfoo(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
+
121
173
### 4-2. Rest 파라미터와 `arguments` 객체
174
+
Rest 파라미터와 `arguments` 객체 간 가장 큰 차이점은 바로 배열이냐 아니냐에 있다.<br/>
175
+
`arguments` 객체는 유사 배열 객체이므로 반드시 배열로 변환해야만 배열 메서드를 사용할 수 있는 반면,<br/>
176
+
**Rest 파라미터는 배열**이므로 `map`이나 `filter` 같은 배열 메서드를 곧바로 사용할 수 있다.
0 commit comments