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/07-new-function/article.md
+1-5Lines changed: 1 addition & 5 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -92,11 +92,7 @@ getFunc()(); // getFunc의 렉시컬 환경에 있는 값 *!*"test"*/!*가 출
92
92
93
93
그런데 스크립트가 프로덕션 서버에 반영되기 전, *압축기(minifier)* 에 의해 압축될 때 문제가 발생합니다. 압축기는 스크립트에서 주석이나 여분의 공백 등을 없애 코드 크기를 줄여주는 특수한 프로그램인데 압축기가 지역 변수 이름을 짧게 바꾸면서 문제가 발생하죠.
94
94
95
-
<<<<<<< HEAD
96
-
구체적으로 어떤 부분이 문제가 되는지 예시를 통해 알아봅시다. 함수 내부에 `let userName`라는 변수가 있으면 이 지역변수는 압축기에 의해 `let a` 등(짧은 이름)으로 대체되는데, 이때 `userName` 모두가 `a`로 교체됩니다. `userName`은 지역변수이고, 함수 외부에선 함수 내부에 있는 변수에 접근할 수 없기 때문에 이렇게 해도 전혀 문제가 없죠. 압축기는 단순히 변수를 찾아서 바꾸지 않고 코드 구조를 분석해 기존에 작성한 코드의 기능을 망가뜨리지 않으면서 영리하게 제 역할을 수행합니다.
97
-
=======
98
-
For instance, if a function has `let userName`, minifier replaces it with `let a` (or another letter if this one is occupied), and does it everywhere. That's usually a safe thing to do, because the variable is local, nothing outside the function can access it. And inside the function, minifier replaces every mention of it. Minifiers are smart, they analyze the code structure, so they don't break anything. They're not just a dumb find-and-replace.
99
-
>>>>>>> upstream/master
95
+
구체적으로 어떤 부분이 문제가 되는지 예시를 통해 알아봅시다. 함수 내부에 `let userName`라는 변수가 있으면 이 지역변수는 압축기에 의해 `let a` 등(해당 글자가 이미 사용 중이라면 다른 짧은 이름)으로 대체되는데, 이때 `userName` 모두가 `a`로 교체됩니다. `userName`은 지역변수이고, 함수 외부에선 함수 내부에 있는 변수에 접근할 수 없기 때문에 이렇게 해도 전혀 문제가 없죠. 압축기는 단순히 찾아바꾸기가 아니라 코드 구조를 분석해 기존 코드의 기능을 망가뜨리지 않으면서 영리하게 제 역할을 수행합니다.
100
96
101
97
이런 동작 방식 때문에 `new Function` 문법으로 만든 함수 내부에서 외부 변수에 접근하려고 하면 `userName`은 이미 이름이 변경되었기 때문에 찾을 수 없게 됩니다.
: 실행 전 대기 시간으로, 단위는 밀리초(millisecond, 1000밀리초 = 1초)이며 기본값은 0입니다.
28
28
29
29
`arg1`, `arg2`...
30
-
<<<<<<< HEAD
31
-
: 함수에 전달할 인수들로, IE9 이하에선 지원하지 않습니다.
32
-
=======
33
-
: Arguments for the function
34
-
>>>>>>> upstream/master
30
+
: 함수에 전달할 인수입니다.
35
31
36
32
예시를 통해 `setTimeout`을 어떻게 쓸 수 있는지 알아봅시다. 아래 코드를 실행하면 1초 후에 `sayHi()`가 호출됩니다.
37
33
@@ -106,11 +102,7 @@ alert(timerId); // 위 타이머 식별자와 동일함 (취소 후에도 식별
106
102
107
103
다시 한번 말씀드리자면, 스케줄링에 관한 명세는 따로 존재하지 않습니다. 명세가 없기 때문에 호스트 환경마다 약간의 차이가 있을 수밖에 없습니다.
108
104
109
-
<<<<<<< HEAD
110
-
참고로 브라우저는 HTML5의 [timers section](https://www.w3.org/TR/html5/webappapis.html#timers)을 준수하고 있습니다.
111
-
=======
112
-
For browsers, timers are described in the [timers section](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) of HTML Living Standard.
113
-
>>>>>>> upstream/master
105
+
참고로 브라우저는 HTML Living Standard의 [timers section](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers)을 준수하고 있습니다.
```smart header="`alert` 창이 떠 있더라도 타이머는 멈추지 않습니다."
138
130
Chrome과 Firefox를 포함한 대부분의 브라우저는 `alert/confirm/prompt` 창이 떠 있는 동안에도 내부 타이머를 멈추지 않습니다.
139
131
140
-
<<<<<<< HEAD
141
132
위 예시를 실행하고 첫 번째 `alert` 창이 떴을 때 몇 초간 기다렸다가 창을 닫으면, 두 번째 `alert` 창이 바로 나타나는 것을 보고 이를 확인할 수 있습니다. 이런 이유로 얼럿 창은 명시한 지연 시간인 2초보다 더 짧은 간격으로 뜨게 됩니다.
142
-
=======
143
-
So if you run the code above and don't dismiss the `alert` window for some time, then the next `alert` will be shown immediately as you do it. The actual interval between alerts will be shorter than 2 seconds.
144
-
>>>>>>> upstream/master
145
133
```
146
134
147
135
## 중첩 setTimeout
@@ -230,11 +218,7 @@ setTimeout(function run() {
230
218
231
219

232
220
233
-
<<<<<<< HEAD
234
-
**중첩 `setTimeout`을 사용하면 명시한 지연(여기서는 100ms)이 보장됩니다.**
235
-
=======
236
-
**The nested `setTimeout` ensures a minimum delay (100ms here) between the end of one call and the beginning of the subsequent one.**
237
-
>>>>>>> upstream/master
221
+
**중첩 `setTimeout`을 사용하면 이전 호출이 끝난 후 다음 호출이 시작되기까지 명시한 지연(여기서는 100ms)이 보장됩니다.**
238
222
239
223
이렇게 지연 간격이 보장되는 이유는 이전 함수의 실행이 종료된 이후에 다음 함수 호출에 대한 계획이 세워지기 때문입니다.
`setInterval`의 경우는, `clearInterval`이 호출되기 전까지 함수에 대한 참조가 메모리에 유지됩니다.
250
234
251
-
<<<<<<< HEAD
252
235
그런데 이런 동작 방식에는 부작용이 하나 있습니다. 외부 렉시컬 환경을 참조하는 함수가 있다고 가정해 봅시다. 이 함수가 메모리에 남아있는 동안엔 외부 변수 역시 메모리에 남아있기 마련입니다. 그런데 이렇게 되면 실제 함수가 차지했어야 하는 공간보다 더 많은 메모리 공간이 사용됩니다. 이런 부작용을 방지하고 싶다면 스케줄링할 필요가 없어진 함수는 아무리 작더라도 취소하도록 합시다.
253
-
=======
254
-
There's a side effect. A function references the outer lexical environment, so, while it lives, outer variables live too. They may take much more memory than the function itself. So when we don't need the scheduled function anymore, it's better to cancel it, even if it's very small.
255
-
>>>>>>> upstream/master
256
236
````
257
237
258
238
## 대기 시간이 0인 setTimeout
@@ -275,13 +255,8 @@ alert("Hello");
275
255
276
256
대기 시간이 0인 setTimeout을 활용한 브라우저 환경에서의 유스 케이스는 <info:event-loop>에서 자세히 다루도록 하겠습니다.
277
257
278
-
<<<<<<< HEAD
279
-
````smart header="브라우저 환경에서 실제 대기 시간은 0이 아닙니다."
280
-
브라우저는 [HTML5 표준](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers)에서 정한 중첩 타이머 실행 간격 관련 제약을 준수합니다. 해당 표준엔 "다섯 번째 중첩 타이머 이후엔 대기 시간을 최소 4밀리초 이상으로 강제해야 한다."라는 제약이 명시되어있습니다.
281
-
=======
282
-
````smart header="Zero delay is in fact not zero (in a browser)"
283
-
In the browser, there's a limitation of how often nested timers can run. The [HTML Living Standard](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers) says: "after five nested timers, the interval is forced to be at least 4 milliseconds.".
284
-
>>>>>>> upstream/master
258
+
````smart header="실제로 지연시간이 0인 경우는 없습니다(브라우저 환경)."
259
+
브라우저는 [HTML Living Standard](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers)에서 정한 중첩 타이머 실행 간격 관련 제약을 준수합니다. 해당 표준엔 "다섯 번째 중첩 타이머 이후엔 대기 시간을 최소 4밀리초 이상으로 강제해야 한다."라는 제약을 명시합니다.
285
260
286
261
예시를 보며 이 제약 사항을 이해해봅시다. 예시 내 `setTimeout`은 지연 없이 함수 run을 다시 호출할 수 있게 스케줄링 되어 있습니다. 배열 `times`에는 실제 지연 간격에 대한 정보가 기록되도록 해놓았는데, 배열 times에 어떤 값이 저장되는지 알아봅시다.
287
262
@@ -306,41 +281,22 @@ setTimeout(function run() {
306
281
307
282
이는 오래전부터 있던 제약인데, 구식 스크립트 중 일부는 아직 이 제약에 의존하는 경우가 있어서 명세서를 변경하지 못하고 있는 상황입니다.
308
283
309
-
<<<<<<< HEAD
310
-
한편, 서버 측엔 이런 제약이 없습니다. Node.js의 [process.nextTick](https://nodejs.org/api/process.html)과 [setImmediate](https://nodejs.org/api/timers.html)를 이용하면 비동기 작업을 지연 없이 실행할 수 있습니다. 위에서 언급된 제약은 브라우저에 한정됩니다.
311
-
=======
312
-
For server-side JavaScript, that limitation does not exist, and there exist other ways to schedule an immediate asynchronous job, like [setImmediate](https://nodejs.org/api/timers.html#timers_setimmediate_callback_args) for Node.js. So this note is browser-specific.
313
-
>>>>>>> upstream/master
284
+
한편, 서버 측엔 이런 제약이 없습니다. Node.js의 [setImmediate](https://nodejs.org/api/timers.html#timers_setimmediate_callback_args)와 같은 방법으로 비동기 작업을 즉시 실행할 수 있습니다. 위에서 언급된 제약은 브라우저에 한정합니다.
314
285
````
315
286
316
287
## 요약
317
288
318
-
<<<<<<< HEAD
319
289
-`setInterval(func, delay, ...args)`과 `setTimeout(func, delay, ...args)`은 `delay`밀리초 후에 `func`을 규칙적으로, 또는 한번 실행하도록 해줍니다.
320
-
-`setInterval·setTimeout`을 호출하고 반환받은 값을 `clearInterval·clearTimeout`에 넘겨주면 스케줄링을 취소할 수 있습니다.
290
+
-`setTimeout·setInterval`을 호출하고 반환받은 값을 `clearTimeout·clearInterval`에 넘겨주면 스케줄링을 취소할 수 있습니다.
321
291
- 중첩 `setTimeout`을 사용하면 `setInterval`을 사용한 것보다 유연하게 코드를 작성할 수 있습니다. 여기에 더하여 *지연 간격* 보장이라는 장점도 있습니다.
322
292
- 대기 시간이 0인 setTimeout(`setTimeout(func, 0)` 혹은 `setTimeout(func)`)을 사용하면 '현재 스크립트의 실행이 완료된 후 가능한 한 빠르게' 원하는 함수를 호출할 수 있습니다.
323
293
- 지연 없이 중첩 `setTimeout`을 5회 이상 호출하거나 지연 없는 `setInterval`에서 호출이 5회 이상 이뤄지면, 4밀리초 이상의 지연 간격이 강제로 더해집니다. 이는 브라우저에만 적용되는 사항이며, 하위 호환성을 위해 유지되고 있습니다.
324
-
=======
325
-
- Methods `setTimeout(func, delay, ...args)` and `setInterval(func, delay, ...args)` allow us to run the `func` once/regularly after `delay` milliseconds.
326
-
- To cancel the execution, we should call `clearTimeout/clearInterval` with the value returned by `setTimeout/setInterval`.
327
-
- Nested `setTimeout` calls are a more flexible alternative to `setInterval`, allowing us to set the time *between* executions more precisely.
328
-
- Zero delay scheduling with `setTimeout(func, 0)` (the same as `setTimeout(func)`) is used to schedule the call "as soon as possible, but after the current script is complete".
329
-
- The browser limits the minimal delay for five or more nested calls of `setTimeout` or for `setInterval` (after 5th call) to 4ms. That's for historical reasons.
330
-
>>>>>>> upstream/master
331
294
332
295
스케줄링 메서드를 사용할 땐 명시한 지연 간격이 *보장*되지 않을 수도 있다는 점에 유의해야 합니다.
333
296
334
-
<<<<<<< HEAD
335
297
아래와 같은 상황에서 브라우저 내 타이머가 느려지면 지연 간격이 보장되지 않습니다.
336
298
- CPU가 과부하 상태인 경우
337
299
- 브라우저 탭이 백그라운드 모드인 경우
338
-
- 노트북이 배터리에 의존해서 구동 중인 경우
339
-
=======
340
-
For example, the in-browser timer may slow down for a lot of reasons:
341
-
- The CPU is overloaded.
342
-
- The browser tab is in the background mode.
343
-
- The laptop is on battery saving mode.
344
-
>>>>>>> upstream/master
300
+
- 노트북이 배터리 절약 모드인 경우
345
301
346
302
이런 상황에서 타이머의 최소 지연 시간은 300밀리초에서 심하면 1,000밀리초까지 늘어납니다. 연장 시간은 브라우저나 구동 중인 운영 체제의 성능 설정에 따라 다릅니다.
Copy file name to clipboardExpand all lines: 1-js/06-advanced-functions/09-call-apply-decorators/article.md
+7-29Lines changed: 7 additions & 29 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -36,19 +36,11 @@ function cachingDecorator(func) {
36
36
37
37
slow =cachingDecorator(slow);
38
38
39
-
<<<<<<<HEAD
40
-
alert( slow(1) ); // slow(1)이 저장되었습니다.
41
-
alert( "다시 호출: "+slow(1) ); // 동일한 결과
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
39
+
alert( slow(1) ); // slow(1)를 캐싱하고 결과를 반환합니다.
40
+
alert( "다시 호출: "+slow(1) ); // 캐시에서 slow(1)의 결과를 가져옵니다.
41
+
42
+
alert( slow(2) ); // slow(2)를 캐싱하고 결과를 반환합니다.
43
+
alert( "다시 호출: "+slow(2) ); // 캐시에서 slow(2)의 결과를 가져옵니다.
52
44
```
53
45
54
46
`cachingDecorator`같이 인수로 받은 함수의 행동을 변경시켜주는 함수를 *데코레이터(decorator)* 라고 부릅니다.
@@ -309,32 +301,18 @@ func.apply(context, args)
309
301
따라서 아래 코드 두 줄은 거의 같은 역할을 합니다.
310
302
311
303
```js
312
-
<<<<<<<HEAD
313
-
func.call(context, ...args); // 전개 구문을 사용해 인수가 담긴 배열을 전달하는 것과
314
-
func.apply(context, args); // call을 사용하는 것은 동일합니다.
315
-
```
316
-
317
-
그런데 약간의 차이가 있긴 합니다.
318
-
=======
319
304
func.call(context, ...args);
320
305
func.apply(context, args);
321
306
```
322
307
323
-
They perform the same call of `func` with given context and arguments.
308
+
위 코드는 `func`을 동일한 컨텍스트와 인수로 호출합니다.
324
309
325
-
There's only a subtle difference regarding `args`:
326
-
>>>>>>> upstream/master
310
+
그런데 `args`에 관해 약간의 차이가 있긴 합니다.
327
311
328
312
- 전개 구문 `...`은 *이터러블*`args`을 분해 해 `call`에 전달할 수 있도록 해줍니다.
329
313
-`apply`는 오직 *유사 배열* 형태의 `args`만 받습니다.
330
314
331
-
<<<<<<< HEAD
332
-
이 차이만 빼면 두 메서드는 완전히 동일하게 동작합니다. 인수가 이터러블 형태라면 `call`을, 유사 배열 형태라면 `apply`를 사용하면 됩니다.
333
-
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
317
이렇게 컨텍스트와 함께 인수 전체를 다른 함수에 전달하는 것을 *콜 포워딩(call forwarding)* 이라고 합니다.
Copy file name to clipboardExpand all lines: 1-js/06-advanced-functions/10-bind/article.md
+3-20Lines changed: 3 additions & 20 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -123,11 +123,7 @@ funcUser(); // John
123
123
*/!*
124
124
```
125
125
126
-
<<<<<<< HEAD
127
-
여기서 `func.bind(user)`는 `func`의 `this`를 `user`로 '바인딩한 변형'이라고 생각하시면 됩니다.
128
-
=======
129
-
Here `func.bind(user)` is a "bound variant" of `func`, with fixed `this=user`.
130
-
>>>>>>> upstream/master
126
+
여기서 `func.bind(user)`는 `this=user`로 고정된 `func`의 '바인딩한 변형'이라고 생각하면 됩니다.
131
127
132
128
인수는 원본 함수 `func`에 '그대로' 전달됩니다.
133
129
@@ -189,13 +185,8 @@ let user = {
189
185
190
186
let say =user.say.bind(user);
191
187
192
-
<<<<<<<HEAD
193
188
say("Hello"); // Hello, John (인수 "Hello"가 say로 전달되었습니다.)
194
189
say("Bye"); // Bye, John ("Bye"가 say로 전달되었습니다.)
195
-
=======
196
-
say("Hello"); // Hello, John! ("Hello" argument is passed to say)
197
-
say("Bye"); // Bye, John! ("Bye" is passed to say)
198
-
>>>>>>> upstream/master
199
190
```
200
191
201
192
````smart header="`bindAll`로 메서드 전체 바인딩하기"
@@ -209,11 +200,7 @@ for (let key in user) {
209
200
}
210
201
```
211
202
212
-
<<<<<<< HEAD
213
-
자바스크립트 라이브러리를 사용해도 대규모 바인딩을 할 수 있습니다. lodash 라이브러리의 [_.bindAll(object, methodNames)](http://lodash.com/docs#bindAll)이 그 예입니다.
214
-
=======
215
-
JavaScript libraries also provide functions for convenient mass binding , e.g. [_.bindAll(object, methodNames)](https://lodash.com/docs#bindAll) in lodash.
216
-
>>>>>>> upstream/master
203
+
자바스크립트 라이브러리를 사용해도 대규모 바인딩을 할 수 있습니다. lodash 라이브러리의 [_.bindAll(object, methodNames)](https://lodash.com/docs#bindAll)이 그 예입니다.
0 commit comments