Skip to content

Commit fc29b7d

Browse files
committed
[20장]strict mode
1 parent 7de5a5a commit fc29b7d

File tree

2 files changed

+249
-0
lines changed

2 files changed

+249
-0
lines changed
22.9 KB
Loading

[20장]strict mode/김순요.md

+249
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,249 @@
1+
# 20장 strict mode
2+
3+
## strict mode란?
4+
5+
- ES5부터 추가
6+
- 한국어로 **엄격 모드**라고 부름
7+
- 자바스크립트 언어의 문법을 좀 더 엄격하게 적용하여 오류를 발생시킬 가능성이 높거나 자바스크립트 엔진의 최적화 작업에 문제를 일으킬 수 있는 코드에 대해 명시적인 에러를 발생시킴
8+
- 오타나 문법 오류 처럼 사소한 실수에 의한 잠재적인 오류를 발생시키기 어려운 개발환경을 만들고, 그 환경에서 안정적인 코드를 생성하여 개발하려는 것이 목적
9+
- ESlint 같은 린트 도구를 사용해도 유사한 효과를 얻을 수 있다.
10+
- ES6에서 도입된 클래스와 모듈은 기본적으로 strict mode가 적용된다.
11+
- IE9 이하는 지원하지 않는다.
12+
13+
### example)
14+
15+
**자바스크립트의 암묵적 전역**
16+
17+
```jsx
18+
function foo() {
19+
x = 10;
20+
}
21+
22+
console.log(x); // 10
23+
```
24+
25+
- x를 선언하지 않았지만 `스코프 체인` 을 통해 x 변수가 어디에서 선언되었는지 검색
26+
1. foo 함수의 스코프에서 x 변수의 선언을 검색 → 실패
27+
2. foo 함수 컨텍스트의 상위 스코프(위 예제에서는 전역 스코프)에서 x 변수 선언을 검색 → 실패
28+
3. 자바스크립트는 ReferenceError를 발생시키지 않고 전역 객체에 x프로퍼티를 동적 생성 → 이를 **암묵적 전역** 이라고 부른다.
29+
- 암묵적 전역은 개발자의 의도와 상관없는 에러를 일으킬 확률이 크므로 **let, var, const** 키워드를 사용하여 변수를 선언한 다음 사용을 해야 함
30+
- 또한 **strict mode**를 사용하여 오류를 방지할 수 있음
31+
32+
> **린트 도구**
33+
>
34+
> `정적 분석(static analysis)` 기능을 통해 소스코드를 실행하기 전에 소스코드를 스캔하여 문법적 오류만이 아니라 잠재적 오류까지 찾아내고 오류의 원인을 리포팅 해주는 도구.
35+
>
36+
> 대표적으로 ESlint가 있다.
37+
>
38+
>
39+
> ![Untitled](./assets/Untitled.png)
40+
>
41+
42+
## strict mode의 적용
43+
44+
- 전역의 선두 또는 함수 몸체의 선두에 `'use strict';` 를 추가한다. 전역에 추가하면 스크립트 전체에 strict mode가 적용된다.
45+
46+
```jsx
47+
// 전역에 strict mode의 적용하는 것은 바람직하지 않다!
48+
'use strict';
49+
50+
function foo() {
51+
x = 10; // ReferenceError: x is not defined
52+
}
53+
foo();
54+
```
55+
56+
- 함수 몸체의 선두에 추가하면 해당 함수와 중첩 함수에 strict mode가 적용된다.
57+
58+
```jsx
59+
// 함수 단위로 strict mode 적용
60+
function foo() {
61+
'use strict';
62+
63+
x = 10; // ReferenceError: x is not defined
64+
}
65+
foo();
66+
```
67+
68+
- 코드의 선두에 `‘use strict’;` 를 위치시키지 않으면 엄격 모드가 제대로 동작하지 않는다.
69+
70+
```jsx
71+
function foo() {
72+
x = 10; // 에러를 발생시키지 않는다.
73+
'use strict';
74+
}
75+
foo();
76+
```
77+
78+
## strict mode의 올바른 사용법
79+
80+
- 전역에 strict mode 를 사용하는 경우 → 권장하지 않음
81+
- 전역에 적용한 script mode는 스크립트 단위로 적용됨
82+
- 아래 예제를 보면 strict mode를 사용한 script가 다른 script에는 영향을 주지 않고 있음을 알 수 있음
83+
84+
```html
85+
<!DOCTYPE html>
86+
<html>
87+
<body>
88+
<script>
89+
'use strict';
90+
</script>
91+
<script>
92+
x = 1; // 에러가 발생하지 않는다.
93+
console.log(x); // 1
94+
</script>
95+
<script>
96+
'use strict';
97+
98+
y = 1; // ReferenceError: y is not defined
99+
console.log(y);
100+
</script>
101+
</body>
102+
</html>
103+
```
104+
105+
- 하지만 strict mode 와 non-strict mode 스크립트를 혼용하는 것은 오류를 발생시킬 수 있다.
106+
- 특히 외부 서드파티 라이브러리를 사용하는 경우 라이브러리가 non-script인 경우도 있기 때문에 전역에 strict mode를 사용하면 라이브러리 사용 시 에러를 발생시킬 수 있으므로, 이러한 경우 스**크립트 전체를 즉시실행함수로 감싸서 스코프를 구분하고 즉시 실행함수의 선두에 strict mode를 적용할 것을 권장**
107+
- 함수 단위로 strict mode를 사용하는 경우 → 권장하지 않음
108+
- strict mode를 사용하는 함수와 사용하지 않는 함수를 혼용하는 것 역시 바람직하지 않다.
109+
- 특히 strict mode가 적용된 함수가 참조할 함수 외부의 컨텍스트에 strict mode를 적용하지 않는 경우도 문제가 생길 수 있다.
110+
111+
```jsx
112+
(function () {
113+
// non-strict mode
114+
var lеt = 10; // 에러가 발생하지 않는다.
115+
116+
function foo() {
117+
'use strict';
118+
119+
let = 20; // SyntaxError: Unexpected strict mode reserved word
120+
}
121+
foo();
122+
}());
123+
```
124+
125+
126+
- 권장되는 방법: **즉시실행함수로 감싼 스크립트 단위로 사용**
127+
128+
```jsx
129+
// 즉시실행 함수에 strict mode 적용
130+
(function () {
131+
'use strict';
132+
133+
// Do something...
134+
135+
}());
136+
```
137+
138+
## strict mode가 발생시키는 에러
139+
140+
### 1. 암묵적 전역
141+
142+
- 선언하지 않는 변수를 참조하면 **ReferenceError**가 발생
143+
144+
```jsx
145+
(function () {
146+
'use strict';
147+
148+
x = 1;
149+
console.log(x); // ReferenceError: x is not defined
150+
}());
151+
```
152+
153+
### 2. 변수, 함수, 매개변수의 삭제
154+
155+
- `delete` 연산자로 변수, 함수, 매개변수를 삭제하면 **SyntaxError**가 발생
156+
157+
```jsx
158+
(function () {
159+
'use strict';
160+
161+
var x = 1;
162+
delete x;
163+
// SyntaxError: Delete of an unqualified identifier in strict mode.
164+
165+
function foo(a) {
166+
delete a;
167+
// SyntaxError: Delete of an unqualified identifier in strict mode.
168+
}
169+
delete foo;
170+
// SyntaxError: Delete of an unqualified identifier in strict mode.
171+
}());
172+
```
173+
174+
### 3. 매개변수 이름의 중복
175+
176+
- 중복된 매개변수 이름을 사용하면 **SyntaxError**가 발생
177+
178+
```jsx
179+
(function () {
180+
'use strict';
181+
182+
//SyntaxError: Duplicate parameter name not allowed in this context
183+
function foo(x, x) {
184+
return x + x;
185+
}
186+
console.log(foo(1, 2));
187+
}());
188+
```
189+
190+
### 4. with문의 사용
191+
192+
- with 문을 사용하면 SyntaxError가 발생
193+
- with문은 전달된 객체를 스코프 체인에 추가하는 역할
194+
- 동일한 객체의 프로퍼티를 반복해서 사용할 때 객체 이름을 생략할 수 있어 코드가 간단해지는 효과가 있음
195+
- 그러나 성능과 가독성이 나빠진다는 단점이 있으므로 사용하지 않는 것을 권장
196+
197+
```jsx
198+
(function () {
199+
'use strict';
200+
201+
// SyntaxError: Strict mode code may not include a with statement
202+
with({ x: 1 }) {
203+
console.log(x);
204+
}
205+
}());
206+
```
207+
208+
## strict mode 적용에 의한 변화
209+
210+
### 일반 함수의 this
211+
212+
- strict mode에서 함수를 일반 함수로 호출하면 this에 `undefined` 가 바인딩
213+
- 생성자 함수가 아닌 일반 함수 내부에서는 this를 사용할 필요가 없기 때문
214+
215+
```jsx
216+
(function () {
217+
'use strict';
218+
219+
function foo() {
220+
console.log(this); // undefined
221+
}
222+
foo();
223+
224+
function Foo() {
225+
console.log(this); // Foo
226+
}
227+
new Foo();
228+
}());
229+
```
230+
231+
### arguments 객체
232+
233+
- strict mode에서는 매개변수에 전달된 인수를 재할당하여 변경해도 arguments 객체에 반영되지 않음
234+
235+
```jsx
236+
(function (a) {
237+
'use strict';
238+
239+
// 매개변수에 전달된 인수를 재할당하여 변경
240+
a = 2;
241+
242+
// 변경된 인수가 arguments 객체에는 반영되지 않는다.
243+
console.log(arguments); // {0: 1, length: 1}
244+
245+
}(1));
246+
```
247+
248+
249+

0 commit comments

Comments
 (0)