Skip to content

Commit f2713c0

Browse files
committed
fix: Prettier 자동 포맷팅 되돌리기 및 충돌 재해결
1 parent ffbdc57 commit f2713c0

8 files changed

Lines changed: 113 additions & 128 deletions

File tree

1-js/06-advanced-functions/07-new-function/article.md

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
12
# new Function 문법
23

34
함수 표현식과 함수 선언문 이외에 함수를 만들 수도 있는 방법이 하나 더 있습니다. 잘 사용하는 방법은 아니지만, 이 방법 외에는 대안이 없을 때 사용합니다.
@@ -7,17 +8,17 @@
78
`new Function` 문법을 사용하면 함수를 만들 수 있습니다.
89

910
```js
10-
let func = new Function([arg1, arg2, ...argN], functionBody);
11+
let func = new Function ([arg1, arg2, ...argN], functionBody);
1112
```
1213

1314
새로 만들어지는 함수는 인수 `arg1...argN`과 함수 본문 `functionBody`로 구성됩니다.
1415

1516
인수 두 개가 있는 함수를 직접 만들어 보면서 `new Function` 문법에 대해 이해해보도록 합시다.
1617

1718
```js run
18-
let sum = new Function("a", "b", "return a + b");
19+
let sum = new Function('a', 'b', 'return a + b');
1920

20-
alert(sum(1, 2)); // 3
21+
alert( sum(1, 2) ); // 3
2122
```
2223

2324
인수가 없고 함수 본문만 있는 함수를 만들어보겠습니다.
@@ -45,11 +46,11 @@ func();
4546

4647
## 클로저
4748

48-
함수는 특별한 프로퍼티 `[[Environment]]`에 저장된 정보를 이용해 자기 자신이 태어난 곳을 기억합니다. `[[Environment]]`는 함수가 만들어진 렉시컬 환경을 참조합니다(자세한 내용은 <info:closure>에서 다루었습니다).
49+
함수는 특별한 프로퍼티 `[[Environment]]`에 저장된 정보를 이용해 자기 자신이 태어난 곳을 기억합니다. `[[Environment]]`는 함수가 만들어진 렉시컬 환경을 참조합니다(자세한 내용은 <info:closure>에서 다루었습니다).
4950

5051
그런데 `new Function`을 이용해 함수를 만들면 함수의 `[[Environment]]` 프로퍼티가 현재 렉시컬 환경이 아닌 전역 렉시컬 환경을 참조하게 됩니다.
5152

52-
따라서 `new Function`을 이용해 만든 함수는 외부 변수에 접근할 수 없고, 오직 전역 변수에만 접근할 수 있습니다.
53+
따라서 `new Function`을 이용해 만든 함수는 외부 변수에 접근할 수 없고, 오직 전역 변수에만 접근할 수 있습니다.
5354

5455
```js run
5556
function getFunc() {
@@ -89,7 +90,7 @@ getFunc()(); // getFunc의 렉시컬 환경에 있는 값 *!*"test"*/!*가 출
8990

9091
`new Function`으로 만든 새로운 함수 내부에서 외부 변수에 접근하려 할 때, 기존 함수 선언 방식으로 작성한 함수와 동일한 동작이 보장되어야 하죠.
9192

92-
그런데 스크립트가 프로덕션 서버에 반영되기 전, _압축기(minifier)_ 에 의해 압축될 때 문제가 발생합니다. 압축기는 스크립트에서 주석이나 여분의 공백 등을 없애 코드 크기를 줄여주는 특수한 프로그램인데 압축기가 지역 변수 이름을 짧게 바꾸면서 문제가 발생하죠.
93+
그런데 스크립트가 프로덕션 서버에 반영되기 전, *압축기(minifier)* 에 의해 압축될 때 문제가 발생합니다. 압축기는 스크립트에서 주석이나 여분의 공백 등을 없애 코드 크기를 줄여주는 특수한 프로그램인데 압축기가 지역 변수 이름을 짧게 바꾸면서 문제가 발생하죠.
9394

9495
구체적으로 어떤 부분이 문제가 되는지 예시를 통해 알아봅시다. 함수 내부에 `let userName`라는 변수가 있으면 이 지역변수는 압축기에 의해 `let a` 등(해당 글자가 이미 사용 중이라면 다른 짧은 이름)으로 대체되는데, 이때 `userName` 모두가 `a`로 교체됩니다. `userName`은 지역변수이고, 함수 외부에선 함수 내부에 있는 변수에 접근할 수 없기 때문에 이렇게 해도 전혀 문제가 없죠. 압축기는 단순히 찾아바꾸기가 아니라 코드 구조를 분석해 기존 코드의 기능을 망가뜨리지 않으면서 영리하게 제 역할을 수행합니다.
9596

@@ -106,17 +107,17 @@ getFunc()(); // getFunc의 렉시컬 환경에 있는 값 *!*"test"*/!*가 출
106107
문법:
107108

108109
```js
109-
let func = new Function([arg1, arg2, ...argN], functionBody);
110+
let func = new Function ([arg1, arg2, ...argN], functionBody);
110111
```
111112

112113
인수를 한꺼번에 모아(쉼표로 구분) 전달할 수도 있습니다.
113114

114115
아래 세 선언 방식은 동일하게 동작하죠.
115116

116117
```js
117-
new Function("a", "b", "return a + b"); // 기본 문법
118-
new Function("a,b", "return a + b"); // 쉼표로 구분
119-
new Function("a , b", "return a + b"); // 쉼표와 공백으로 구분
118+
new Function('a', 'b', 'return a + b'); // 기본 문법
119+
new Function('a,b', 'return a + b'); // 쉼표로 구분
120+
new Function('a , b', 'return a + b'); // 쉼표와 공백으로 구분
120121
```
121122

122123
`new Function`을 이용해 만든 함수의 `[[Environment]]`는 외부 렉시컬 환경이 아닌 전역 렉시컬 환경을 참조하므로 외부 변수를 사용할 수 없습니다. 단점 같아 보이는 특징이긴 하지만 에러를 예방해 준다는 관점에선 장점이 되기도 합니다. 구조상으론 매개변수를 사용해 값을 받는 게 더 낫습니다. 압축기에 의한 에러도 방지할 수 있죠.

1-js/06-advanced-functions/08-settimeout-setinterval/article.md

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ setTimeout("alert('안녕하세요.')", 1000);
6464
그런데 이렇게 문자열을 사용하는 방법은 추천하지 않습니다. 되도록 다음 예시와 같이 익명 화살표 함수를 사용하세요.
6565

6666
```js run no-beautify
67-
setTimeout(() => alert("안녕하세요."), 1000);
67+
setTimeout(() => alert('안녕하세요.'), 1000);
6868
```
6969

7070
````smart header="함수를 실행하지 말고 넘기세요."
@@ -120,21 +120,17 @@ let timerId = setInterval(func|code, [delay], [arg1], [arg2], ...)
120120

121121
```js run
122122
// 2초 간격으로 메시지를 보여줌
123-
let timerId = setInterval(() => alert("째깍"), 2000);
123+
let timerId = setInterval(() => alert('째깍'), 2000);
124124

125125
// 5초 후에 정지
126-
setTimeout(() => {
127-
clearInterval(timerId);
128-
alert("정지");
129-
}, 5000);
126+
setTimeout(() => { clearInterval(timerId); alert('정지'); }, 5000);
130127
```
131128

132-
```smart header="`alert`창이 떠 있더라도 타이머는 멈추지 않습니다."
133-
Chrome과 Firefox를 포함한 대부분의 브라우저는`alert/confirm/prompt` 창이 떠 있는 동안에도 내부 타이머를 멈추지 않습니다.
129+
```smart header="`alert` 창이 떠 있더라도 타이머는 멈추지 않습니다."
130+
Chrome과 Firefox를 포함한 대부분의 브라우저는 `alert/confirm/prompt` 창이 떠 있는 동안에도 내부 타이머를 멈추지 않습니다.
134131

135132
위 예시를 실행하고 첫 번째 `alert` 창이 떴을 때 몇 초간 기다렸다가 창을 닫으면, 두 번째 `alert` 창이 바로 나타나는 것을 보고 이를 확인할 수 있습니다. 이런 이유로 얼럿 창은 명시한 지연 시간인 2초보다 더 짧은 간격으로 뜨게 됩니다.
136-
137-
````
133+
```
138134
139135
## 중첩 setTimeout
140136
@@ -153,7 +149,7 @@ let timerId = setTimeout(function tick() {
153149
timerId = setTimeout(tick, 2000); // (*)
154150
*/!*
155151
}, 2000);
156-
````
152+
```
157153

158154
다섯 번째 줄의 `setTimeout``(*)`로 표시한 줄의 실행이 종료되면 다음 호출을 스케줄링합니다.
159155

@@ -162,7 +158,6 @@ let timerId = setTimeout(function tick() {
162158
5초 간격으로 서버에 요청을 보내 데이터를 얻는다고 가정해 봅시다. 서버가 과부하 상태라면 요청 간격을 10초, 20초, 40초 등으로 증가시켜주는 게 좋을 겁니다.
163159

164160
아래는 이를 구현한 의사 코드입니다.
165-
166161
```js
167162
let delay = 5000;
168163

@@ -179,6 +174,7 @@ let timerId = setTimeout(function request() {
179174
}, delay);
180175
```
181176

177+
182178
CPU 소모가 많은 작업을 주기적으로 실행하는 경우에도 `setTimeout`을 재귀 실행하는 방법이 유용합니다. 작업에 걸리는 시간에 따라 다음 작업을 유동적으로 계획할 수 있기 때문입니다.
183179

184180
**중첩 `setTimeout`을 이용하는 방법은 지연 간격을 보장하지만 `setInterval`은 이를 보장하지 않습니다.**
@@ -187,7 +183,7 @@ CPU 소모가 많은 작업을 주기적으로 실행하는 경우에도 `setTim
187183

188184
```js
189185
let i = 1;
190-
setInterval(function () {
186+
setInterval(function() {
191187
func(i++);
192188
}, 100);
193189
```
@@ -214,7 +210,7 @@ setTimeout(function run() {
214210

215211
그렇다면 `func`을 실행하는 데 걸리는 시간이 명시한 지연 간격보다 길 때 어떤 일이 발생할까요?
216212

217-
이런 경우는 엔진이 `func`의 실행이 종료될 때까지 기다려줍니다. `func`의 실행이 종료되면 엔진은 스케줄러를 확인하고, 지연 시간이 지났으면 다음 호출을 _바로_ 시작합니다.
213+
이런 경우는 엔진이 `func`의 실행이 종료될 때까지 기다려줍니다. `func`의 실행이 종료되면 엔진은 스케줄러를 확인하고, 지연 시간이 지났으면 다음 호출을 *바로* 시작합니다.
218214

219215
따라서 함수 호출에 걸리는 시간이 매번 `delay` 밀리초보다 길면, 모든 함수가 쉼 없이 계속 연속 호출됩니다.
220216

@@ -260,7 +256,7 @@ alert("Hello");
260256
대기 시간이 0인 setTimeout을 활용한 브라우저 환경에서의 유스 케이스는 <info:event-loop>에서 자세히 다루도록 하겠습니다.
261257

262258
````smart header="실제로 지연시간이 0인 경우는 없습니다(브라우저 환경)."
263-
브라우저는 [HTML Living Standard](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers)에서 정한 중첩 타이머 실행 간격 관련 제약을 준수합니다. 해당 표준엔 "다섯 번째 중첩 타이머 이후엔 대기 시간을 최소 4밀리초 이상으로 강제해야 한다."라는 제약이 명시되어 있습니다.
259+
브라우저는 [HTML Living Standard](https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers)에서 정한 중첩 타이머 실행 간격 관련 제약을 준수합니다. 해당 표준엔 "다섯 번째 중첩 타이머 이후엔 대기 시간을 최소 4밀리초 이상으로 강제해야 한다."라는 제약을 명시합니다.
264260
265261
예시를 보며 이 제약 사항을 이해해봅시다. 예시 내 `setTimeout`은 지연 없이 함수 run을 다시 호출할 수 있게 스케줄링 되어 있습니다. 배열 `times`에는 실제 지연 간격에 대한 정보가 기록되도록 해놓았는데, 배열 times에 어떤 값이 저장되는지 알아봅시다.
266262
@@ -292,14 +288,13 @@ setTimeout(function run() {
292288

293289
- `setInterval(func, delay, ...args)``setTimeout(func, delay, ...args)``delay`밀리초 후에 `func`을 규칙적으로, 또는 한번 실행하도록 해줍니다.
294290
- `setTimeout·setInterval`을 호출하고 반환받은 값을 `clearTimeout·clearInterval`에 넘겨주면 스케줄링을 취소할 수 있습니다.
295-
- 중첩 `setTimeout`을 사용하면 `setInterval`을 사용한 것보다 유연하게 코드를 작성할 수 있습니다. 여기에 더하여 실행 _사이의_ 지연 간격을 더 정확하게 조절할 수 있게 해줍니다.
291+
- 중첩 `setTimeout`을 사용하면 `setInterval`을 사용한 것보다 유연하게 코드를 작성할 수 있습니다. 여기에 더하여 실행 *사이의* 지연 간격을 더 정확하게 조절할 수 있게 해줍니다.
296292
- 대기 시간이 0인 setTimeout(`setTimeout(func, 0)` 혹은 `setTimeout(func)`)을 사용하면 '현재 스크립트의 실행이 완료된 후 가능한 한 빠르게' 원하는 함수를 호출할 수 있습니다.
297293
- 지연 없이 중첩 `setTimeout`을 5회 이상 호출하거나 지연 없는 `setInterval`에서 호출이 5회 이상 이뤄지면, 4밀리초 이상의 지연 간격이 강제로 더해집니다. 이는 브라우저에만 적용되는 사항이며, 하위 호환성을 위해 유지되고 있습니다.
298294

299295
스케줄링 메서드를 사용할 땐 명시한 지연 간격이 *보장*되지 않을 수도 있다는 점에 유의해야 합니다.
300296

301297
아래와 같은 여러 이유로 브라우저 내 타이머가 느려질 수 있습니다.
302-
303298
- CPU가 과부하 상태인 경우
304299
- 브라우저 탭이 백그라운드 모드인 경우
305300
- 노트북이 배터리 절약 모드인 경우

0 commit comments

Comments
 (0)