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: 1-js/06-advanced-functions/09-call-apply-decorators/article.md
+32-54Lines changed: 32 additions & 54 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,6 +1,6 @@
1
1
# call/apply와 데코레이터, 포워딩
2
2
3
-
자바스크립트는 함수를 다룰 때 탁월한 유연성을 제공합니다. 함수는 이곳저곳 전달될 수 있고, 객체로도 사용될 수 있습니다. 이번 챕터에선 함수 간에 호출을 어떻게 *포워딩(forwarding)* 하는지, 함수를 어떻게 *데코레이팅(decorating)* 하는지에 대해 알아보겠습니다.
3
+
자바스크립트는 함수를 다룰 때 탁월한 유연성을 제공합니다. 함수는 이곳저곳 전달될 수 있고, 객체로도 사용될 수 있습니다. 이번 챕터에선 함수 간에 호출을 어떻게 _포워딩(forwarding)_ 하는지, 함수를 어떻게 _데코레이팅(decorating)_ 하는지에 대해 알아보겠습니다.
4
4
5
5
## 코드 변경 없이 캐싱 기능 추가하기
6
6
@@ -22,40 +22,33 @@ function slow(x) {
22
22
functioncachingDecorator(func) {
23
23
let cache =newMap();
24
24
25
-
returnfunction(x) {
26
-
if (cache.has(x)) { // cache에 해당 키가 있으면
25
+
returnfunction (x) {
26
+
if (cache.has(x)) {
27
+
// cache에 해당 키가 있으면
27
28
returncache.get(x); // 대응하는 값을 cache에서 읽어옵니다.
28
29
}
29
30
30
-
let result =func(x); // 그렇지 않은 경우엔 func를 호출하고,
31
+
let result =func(x); // 그렇지 않은 경우엔 func를 호출하고,
31
32
32
-
cache.set(x, result); // 그 결과를 캐싱(저장)합니다.
33
+
cache.set(x, result); // 그 결과를 캐싱(저장)합니다.
33
34
return result;
34
35
};
35
36
}
36
37
37
38
slow =cachingDecorator(slow);
38
39
39
-
<<<<<<<HEAD
40
-
alert( slow(1) ); // slow(1)이 저장되었습니다.
41
-
alert( "다시 호출: "+slow(1) ); // 동일한 결과
40
+
alert( slow(1) ); // slow(1)를 캐싱하고 결과를 반환합니다.
41
+
alert( "다시 호출: "+slow(1) ); // 캐시에서 slow(1)의 결과를 가져옵니다.
42
42
43
-
alert( slow(2) ); // slow(2)가 저장되었습니다.
44
-
alert( "다시 호출: "+slow(2) ); // 윗줄과 동일한 결과
45
-
=======
46
-
alert( slow(1) ); // slow(1) is cached and the result returned
47
-
alert( "Again: "+slow(1) ); // slow(1) result returned from cache
48
-
49
-
alert( slow(2) ); // slow(2) is cached and the result returned
50
-
alert( "Again: "+slow(2) ); // slow(2) result returned from cache
51
-
>>>>>>> upstream/master
43
+
alert( slow(2) ); // slow(2)를 캐싱하고 결과를 반환합니다.
44
+
alert( "다시 호출: "+slow(2) ); // 캐시에서 slow(2)의 결과를 가져옵니다.
52
45
```
53
46
54
-
`cachingDecorator`같이 인수로 받은 함수의 행동을 변경시켜주는 함수를 *데코레이터(decorator)* 라고 부릅니다.
47
+
`cachingDecorator`같이 인수로 받은 함수의 행동을 변경시켜주는 함수를 _데코레이터(decorator)_ 라고 부릅니다.
55
48
56
49
모든 함수를 대상으로 `cachingDecorator`를 호출 할 수 있는데, 이때 반환되는 것은 캐싱 래퍼입니다. 함수에 `cachingDecorator`를 적용하기만 하면 캐싱이 가능한 함수를 원하는 만큼 구현할 수 있기 때문에 데코레이터 함수는 아주 유용하게 사용됩니다.
57
50
58
-
캐싱 관련 코드를 함수 코드와 분리할 수 있기 때문에 함수의 코드가 간결해진다는 장점도 있습니다.
51
+
캐싱 관련 코드를 함수 코드와 분리할 수 있기 때문에 함수의 코드가 간결해진다는 장점도 있습니다.
59
52
60
53
아래 그림에서 볼 수 있듯이 `cachingDecorator(func)`를 호출하면 '래퍼(wrapper)', `function(x)`이 반환됩니다. 래퍼 `function(x)`는 `func(x)`의 호출 결과를 캐싱 로직으로 감쌉니다(wrapping).
61
54
@@ -66,7 +59,7 @@ alert( "Again: " + slow(2) ); // slow(2) result returned from cache
66
59
`slow` 본문을 수정하는 것 보다 독립된 래퍼 함수 `cachingDecorator`를 사용할 때 생기는 이점을 정리하면 다음과 같습니다.
67
60
68
61
-`cachingDecorator`를 재사용 할 수 있습니다. 원하는 함수 어디에든 `cachingDecorator`를 적용할 수 있습니다.
69
-
- 캐싱 로직이 분리되어 `slow` 자체의 복잡성이 증가하지 않습니다.
62
+
- 캐싱 로직이 분리되어 `slow` 자체의 복잡성이 증가하지 않습니다.
70
63
- 필요하다면 여러 개의 데코레이터를 조합해서 사용할 수도 있습니다(추가 데코레이터는 `cachingDecorator` 뒤를 따릅니다).
3. 두 값을 하나로 합치기. `맵`의 키로 문자열 `"min,max"`를 사용합니다. 여러 값을 하나로 합치는 코드는 *해싱 함수(hashing function)* 에 구현해 유연성을 높입니다.
236
+
3. 두 값을 하나로 합치기. `맵`의 키로 문자열 `"min,max"`를 사용합니다. 여러 값을 하나로 합치는 코드는 _해싱 함수(hashing function)_ 에 구현해 유연성을 높입니다.
244
237
245
238
세 번째 방법만으로 충분하기 때문에 이 방법을 사용해 코드를 수정해 보겠습니다.
246
239
@@ -299,7 +292,7 @@ alert( "다시 호출: " + worker.slow(3, 5) ); // 동일한 결과 출력(캐
299
292
내장 메서드 [func.apply](mdn:js/Function/apply)의 문법은 다음과 같습니다.
300
293
301
294
```js
302
-
func.apply(context, args)
295
+
func.apply(context, args);
303
296
```
304
297
305
298
`apply`는 `func`의 `this`를 `context`로 고정해주고, 유사 배열 객체인 `args`를 인수로 사용할 수 있게 해줍니다.
@@ -309,39 +302,24 @@ func.apply(context, args)
309
302
따라서 아래 코드 두 줄은 거의 같은 역할을 합니다.
310
303
311
304
```js
312
-
<<<<<<<HEAD
313
-
func.call(context, ...args); // 전개 구문을 사용해 인수가 담긴 배열을 전달하는 것과
314
-
func.apply(context, args); // call을 사용하는 것은 동일합니다.
315
-
```
316
-
317
-
그런데 약간의 차이가 있긴 합니다.
318
-
=======
319
305
func.call(context, ...args);
320
306
func.apply(context, args);
321
307
```
322
308
323
-
They perform the same call of `func` with given context and arguments.
309
+
위 코드는 `func`을 동일한 컨텍스트와 인수로 호출합니다.
310
+
그런데 `args`에 관해 약간의 차이가 있긴 합니다.
324
311
325
-
There's only a subtle difference regarding `args`:
326
-
>>>>>>> upstream/master
327
-
328
-
- 전개 구문 `...`은 *이터러블* `args`을 분해 해 `call`에 전달할 수 있도록 해줍니다.
329
-
- `apply`는 오직 *유사 배열* 형태의 `args`만 받습니다.
330
-
331
-
<<<<<<< HEAD
332
-
이 차이만 빼면 두 메서드는 완전히 동일하게 동작합니다. 인수가 이터러블 형태라면 `call`을, 유사 배열 형태라면 `apply`를 사용하면 됩니다.
312
+
- 전개 구문 `...`은 _이터러블_`args`을 분해 해 `call`에 전달할 수 있도록 해줍니다.
313
+
-`apply`는 오직 _유사 배열_ 형태의 `args`만 받습니다.
333
314
334
315
배열같이 이터러블이면서 유사 배열인 객체엔 둘 다를 사용할 수 있는데, 대부분의 자바스크립트 엔진은 내부에서 `apply`를 최적화 하기 때문에 `apply`를 사용하는 게 좀 더 빠르긴 합니다.
335
-
=======
336
-
...And for objects that are both iterable and array-like, such as a real array, we can use any of them, but `apply` will probably be faster, because most JavaScript engines internally optimize it better.
337
-
>>>>>>> upstream/master
338
316
339
-
이렇게 컨텍스트와 함께 인수 전체를 다른 함수에 전달하는 것을 *콜 포워딩(call forwarding)* 이라고 합니다.
317
+
이렇게 컨텍스트와 함께 인수 전체를 다른 함수에 전달하는 것을 _콜 포워딩(call forwarding)_ 이라고 합니다.
340
318
341
319
가장 간단한 형태의 콜 포워딩은 다음과 같습니다.
342
320
343
321
```js
344
-
let wrapper = function() {
322
+
letwrapper=function() {
345
323
returnfunc.apply(this, arguments);
346
324
};
347
325
```
@@ -354,11 +332,11 @@ let wrapper = function() {
354
332
355
333
```js
356
334
functionhash(args) {
357
-
return args[0] +','+ args[1];
335
+
return args[0] +","+ args[1];
358
336
}
359
337
```
360
338
361
-
지금 상태에선 인수 두 개만 다룰 수 있습니다. `args`의 요소 개수에 상관없이 요소들을 합칠 수 있으면 더 좋겠네요.
339
+
지금 상태에선 인수 두 개만 다룰 수 있습니다. `args`의 요소 개수에 상관없이 요소들을 합칠 수 있으면 더 좋겠네요.
362
340
363
341
가장 자연스러운 해결책은 배열 메서드 [arr.join](mdn:js/Array/join)을 사용하는 것입니다.
364
342
@@ -394,7 +372,7 @@ function hash() {
394
372
hash(1, 2);
395
373
```
396
374
397
-
The trick is called *method borrowing*.
375
+
The trick is called _method borrowing_.
398
376
399
377
일반 배열에서 `join` 메서드를 빌려오고(`[].join`), `[].join.call`를 사용해 `arguments`를 컨텍스트로 고정한 후 `join`메서드를 호출하는 것이죠.
400
378
@@ -438,7 +416,7 @@ The trick is called *method borrowing*.
0 commit comments