1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
|
---
title: Strict mode
slug: Web/JavaScript/Reference/Strict_mode
tags:
- ECMAScript 5
- JavaScript
- 엄격모드
translation_of: Web/JavaScript/Reference/Strict_mode
---
<div>{{JsSidebar("More")}}</div>
<div class="callout-box">가끔 엄격하지 않은 기본값을 "<strong><a href="https://developer.mozilla.org/ko/docs/Glossary/Sloppy_mode">느슨한 모드</a></strong>(sloppy mode)"라고 부르기도 합니다. 공식적인 용어는 아니지만 혹시 모르니 알아두세요.</div>
<div><a class="external" href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMAScript 5</a> 에서 소개된 JavaScript 의 엄격모드는 JavaScript 의 제한된 버전을 선택하여 암묵적인 "<strong><a href="https://developer.mozilla.org/ko/docs/Glossary/Sloppy_mode">느슨한 모드</a></strong>(sloppy mode)" 를 해제하기 위한 방법입니다. 엄격 모드는 단지 부분적인 것이 아니며, 이것은 <em>고의적으로 </em>일반 코드와 다른 시멘틱을 가지고 있습니다. 엄격모드를 지원하지 않는 브라우저에서는 엄격 모드의 코드가 다른 방식으로 동작할 것입니다, 그 때문에 엄격 모드가 적절하게 적용된 피쳐 테스트 없이 엄격 모드에 의존하면 안됩니다. 엄격 모드의 코드와 비-엄격 모드의 코드는 공존할 수 있으며, 때문에 스크립트의 엄격 모드를 취사 선택하는 것이 점진적으로 가능하게 되었습니다.</div>
<div></div>
<p>엄격 모드는 평범한 JavaScript 시멘틱스에 몇가지 변경이 일어나게 합니다.</p>
<ol>
<li>기존에는 조용히 무시되던 에러들을 throwing합니다.</li>
<li>JavaScript 엔진의 최적화 작업을 어렵게 만드는 실수들을 바로잡습니다. 가끔씩 엄격 모드의 코드는 비-엄격 모드의 동일한 코드보다 더 빨리 작동하도록 만들어집니다.</li>
<li>엄격 모드는 ECMAScript의 차기 버전들에서 정의 될 문법을 금지합니다.</li>
</ol>
<p>코드를 JavaScript의 변형이 제한된 환경에서 동작하도록 하고 싶다면, 엄격 모드로의 변환(<a href="/en-US/docs/Web/JavaScript/Reference/Strict_mode/Transitioning_to_strict_mode">transitioning to strict mode</a>)을 참고하세요.</p>
<h2 id="엄격모드_적용하기">엄격모드 적용하기</h2>
<p>엄격모드는 <em>전체 스크립트</em> 또는 <em>부분 함수</em>에 적용가능합니다. 단, <code>{}</code> 괄호로 묶여진 블럭문에는 적용되지 않습니다. 컨텍스트와 같은곳에 적용을 시도하면 동작하지 않습니다. <code>eval</code> 코드, <code>Function</code> 코드, 이벤트 핸들러 속성, {{domxref("WindowTimers.setTimeout()")}} 과 연관된 함수들에 전달된 문자열이 전체 스크립트이며 여기에서 엄격모드가 예상대로 동작합니다. </p>
<h3 id="스크립트_엄격_모드">스크립트 엄격 모드</h3>
<p>엄격모드를 전체 스크립트에 적용하기 위해, 정확한 구문 <code>"use strict";</code>(또는 <code>'use strict';</code>) 을 다른 구문 작성 전에 삽입합니다.</p>
<pre class="brush: js notranslate">// 전체 스크립트 엄격 모드 구문
'use strict';
var v = "Hi! I'm a strict mode script!";
</pre>
<p><span style='background-color: transparent; color: #333333; display: inline !important; float: none; font-family: "Open Sans",arial,x-locale-body,sans-serif; font-size: 16px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal;'>이 구문은 이미 <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=627531">유명한 웹사이트</a>에서 <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=579119">문제를 일으킨 전적</a>이 있습니다. </span>상충되지 않는 스크립트들 끼리 맹목적인 연결이 불가능하기 때문입니다. 엄격 모드의 스크립트와 비-엄격 모드의 스크립트의 연결은 심사숙고 하시기를 바랍니다. 이렇게 되면 전체 연결은 엄격으로 보입니다! 엄격 모드에 다른 엄격모드 들을 결합하는 것은 괜찮습니다. 그리고, 비-엄격 스크립트 사이의 결합도 괜찮습니다. 분명한건, 스크립트를 결합하는 것이 절대 이상적인 것이 아니라는 것이지만, 그래야 한다면 함수를 기준으로 엄격모드 사용을 고려하시기 바랍니다.</p>
<p>또한 함수 내부의 전체 스크립트 내용에 접근할 수 있으며, 엄격모드를 사용하는 외부 함수를 가질 수 있습니다. 이는 결합 문제를 없애주기도 하지만, 이것이 스코프 바깥에 위치한 어떤 전역 변수든 확실하게 밖으로 추출할 수 있음을 의미합니다 . </p>
<h3 id="함수에_strict_mode_적용">함수에 strict mode 적용</h3>
<p>마찬가지로, 함수에 strict mode를 적용하기 위해, 함수 본문 처음에 다음의 구문을 넣습니다. <code>"use strict";</code> (또는 <code>'use strict';</code>).</p>
<pre class="brush: js notranslate">function strict() {
// 함수-레벨 strict mode 문법
'use strict';
function nested() { return "And so am I!"; }
return "Hi! I'm a strict mode function! " + nested();
}
function notStrict() { return "I'm not strict."; }
</pre>
<h3 id="모듈에_strict_mode_적용">모듈에 strict mode 적용</h3>
<p>ECMAScript 2015 는 <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export">JavaScript 모듈</a>을 소개했습니다. 따라서, 이는 엄격 모드를 적용할 수 있는 3번 째 방법입니다. JavaScript 모듈의 전체 컨텐츠는 엄격 모드 시작을 위한 구문 없이도 자동으로 엄격모드입니다.</p>
<pre class="notranslate"><code>function strict() {
// 모듈이기때문에 기본적으로 엄격합니다
}
export default strict;</code>
</pre>
<h2 id="엄격한_모드_변경">엄격한 모드 변경</h2>
<p>엄격한 모드는 구문과 런타임 동작을 모두 변경합니다.<br>
일반적으로 이러한 유형의 변화가 발생합니다: 변환 실수를 오류로 해석하거나(문법 오류 또는 런타임에 오류 발생), 특정 이름의 특정 용도에 대한 특정 변수를 계산하는 방법을 단순화하며, <code>eval</code> 과 <code>arguments</code> 를 단순화하고,"안전한 "자바 스크립트를 작성하도록 돕고, 미래 ECMAScript의 진화에 대비합니다.</p>
<h3 id="실수를_에러로_바꾸는_것">실수를 에러로 바꾸는 것</h3>
<p>엄격한 모드는 일부 이전에 허용되었던 실수를 오류로 바꿔 놓습니다. 자바 스크립트는 초보 개발자에게 쉬운 것이 되도록 설계되었으며, 때로는 오류를 일으킬만한 동작을 에러없이 시행합니다. 때때로 이것은 즉각적인 문제를 해결하지만, 때때로 이것은 더 심각한 문제를 만들어 냅니다. 엄격한 모드는 이러한 실수를 <span style='background-color: transparent; color: #333333; display: inline !important; float: none; font-family: "Open Sans",arial,x-locale-body,sans-serif; font-size: 16px; font-style: normal; font-variant: normal; font-weight: 400; letter-spacing: normal; text-align: left; text-decoration: none; text-indent: 0px; text-transform: none; white-space: normal;'>오류로 처리해서</span> 그것을 발견하고 즉시 고칠 수 있도록 합니다.</p>
<p>첫째로, 엄격모드는 실수로 글로벌 변수를 생성하는 것을 불가능하게 만듭니다. 일반적인 JavaScript에서 변수를 잘못 입력하면 전역 객체에 대한 새 속성이 만들어지고 그대로 "동작" (미래의 오류가 발생할 수 있음: modern 자바 스크립트처럼) 합니다. 전역 변수를 생성하는 할당은 엄격 모드에선 오류를 발생시킵니다.</p>
<pre class="brush: js notranslate">"use strict";
// 전역 변수 mistypedVariable 이 존재한다고 가정
mistypedVaraible = 17; // 변수의 오타때문에 이 라인에서 ReferenceError 를 발생시킴
</pre>
<p>둘째로, 엄격모드는 예외를 발생시키는 실패를 조용히 넘어가는 대신 작업을 만듭니다. 예를 들어, <code>NaN</code> 은 쓸 수 없는 전역 변수입니다. <code>NaN</code> 에 할당하는 일반적인 코드는 아무 것도 하지 않습니다. 개발자도 아무런 실패 피드백을 받지 않습니다. 엄격 모드에서 <code>NaN</code> 에 할당하는 것은 예외를 발생시킵니다. 일반 코드에서 조용히 넘어가는 모든 실패에 대해 (쓸 수 없는 전역 또는 프로퍼티에 할당, getter-only 프로퍼티에 할당, <a href="https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions" title="en-US/JavaScript/Reference/Global Objects/Object/preventExtensions">확장 불가</a> 객체에 새 프로퍼티 할당) 엄격 모드에서는 예외를 발생시킵니다.</p>
<pre class="brush: js notranslate">"use strict";
// 쓸 수 없는 프로퍼티에 할당
var undefined = 5; // TypeError 발생
var Infinity = 5; // TypeError 발생
// 쓸 수 없는 프로퍼티에 할당
var obj1 = {};
Object.defineProperty(obj1, "x", { value: 42, writable: false });
obj1.x = 9; // TypeError 발생
// getter-only 프로퍼티에 할당
var obj2 = { get x() { return 17; } };
obj2.x = 5; // TypeError 발생
// 확장 불가 객체에 새 프로퍼티 할당
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = "ohai"; // TypeError 발생
</pre>
<p>셋째로, 엄격 모드는 삭제할 수 없는 프로퍼티를 삭제하려할 때 예외를 발생시킵니다(시도가 어떤 효과도 없을 때).</p>
<pre class="brush: js notranslate">"use strict";
delete Object.prototype; // TypeError 발생
</pre>
<p>넷째로, Gecko 34 이전의 엄격모드는 객체 리터럴의 모든 프로퍼티의 이름이 유니크해도록 요구합니다. 일반 코드는 프로퍼티의 값이 나중에 정해진 프로퍼티 이름으로 중복할 것입니다. 하지만 마지막 인스턴스 만 변경했기 때문에 코드를 수정하여 마지막 인스턴스를 변경하는 것 이외의 속성 값을 변경하면 복제는 버그의 벡터가됩니다. 엄격모드에서는 프로퍼티 이름을 중복하는 것은 구문 에러입니다.</p>
<div class="note">
<p>ECMAScript 2015부터는 에러가 아닙니다. ({{bug(1041128)}}).</p>
</div>
<pre class="brush: js notranslate">"use strict";
var o = { p: 1, p: 2 }; // !!! 구문 에러
</pre>
<p>다섯째로, 엄격모드는 유니크한 함수 파라미터 이름을 요구합니다. 일반 코드에서는 마지막으로 중복된 인수가 이전에 지정된 인수를 숨깁니다. 이러한 이전의 인수들은 <code>arguments[i]</code> 를 통해 여전히 남아 있을 수 있으므로, 완전히 접근 불가한 것이 아닙니다. 여전히, 이런 숨김 처리는 이치에 맞지 않으며 원했던 것이 아닐 수 있습니다(예를 들면 오타를 숨길 수도 있습니다). 따라서 엄격 모드에서는 중복 인수명은 구문 에러입니다.</p>
<pre class="brush: js notranslate">function sum(a, a, c){ // !!! 구문 에러
"use strict";
return a + b + c; // 코드가 실행되면 잘못된 것임
}
</pre>
<p>여섯째로, ECMAScript 5 에서의 엄격 모드는 8진 구문을 금지합니다. 8진 구문은 ES5의 문법이 아니지만, 모든 브라우저에서 앞에 0을 붙여 지원됩니다(<code>0644 === 420</code> 와 <code>"\045" === "%"</code>). ECMAScript 2015 에서는 접두사 "<code>0o</code>"를 붙여 8진수를 지원합니다.</p>
<pre class="brush: js notranslate">var a = 0o10; // ES6: 8진수</pre>
<p>초보 개발자들은 가끔 앞에 붙은 0 이 무의미하다고 생각하여, 이를 정렬용으로 사용합니다 — 하지만 이는 숫자의 의미를 바꿔버립니다! 이 8진수 문법은 거의 무용하며 잘못 사용될 수 있으므로 엄격모드에서 이 구문은 에러입니다.</p>
<pre class="brush: js notranslate">"use strict";
var sum = 015 + // !!! 구문 에러
197 +
142;
</pre>
<p>일곱째로, ECMAScript 6 의 엄격모드는 {{Glossary("primitive")}} 값에 프로퍼티를 설정하는 것을 금지합니다. 엄격모드가 아닐 때에는 프로퍼티 설정이 간단하게 무시되지만(no-op), 엄격모드에서는 {{jsxref("TypeError")}} 를 발생시킵니다.</p>
<pre class="brush: js notranslate">(function() {
"use strict";
false.true = ""; // TypeError
(14).sailing = "home"; // TypeError
"with".you = "far away"; // TypeError
})();</pre>
<h3 id="변수_사용_단순화">변수 사용 단순화</h3>
<p>엄격모드는 코드상의 변수 이름을 특정 변수 정의로 매핑하는 방법을 단순화합니다. 많은 컴파일러 최적화는 변수 X 가 어떤 위치에 저장되어 있는지를 말해주는 능력에 의존하고 있습니다. 이는 자바스크립트 코드를 완전히 최적화하는데 중요합니다. 자바스크립트는 때때로 이름을 코드상의 변수 정의로 기본 매핑하는 것을 런타임때까지 실행이 불가하게합니다. 엄격모드는 이것이 발생하는 대부분의 경우를 제거하여 컴파일러가 엄격모드 코드를 더 잘 최적화 할 수 있게합니다.</p>
<p>첫째로, 엄격모드는 <code>with</code> 를 사용하지 못하게합니다. <code>with</code> 사용의 문제는 런타임중에 블록안의 모든 이름이 전달된 객체의 프로퍼티나 인근 (또는 심지어 전역) 스코프 내의 변수로 매핑될 수도 있다는 것입니다. 이는 사전에 아는 것이 불가합니다. 엄격 모드는 <code>with</code> 를 구문 에러로 만들어, <code>with</code> 의 이름이 런타임에 알 수 없는 위치를 참조하지 않도록합니다.</p>
<pre class="brush: js notranslate">"use strict";
var x = 17;
with (obj) // !!! 구문 에러
{
// 엄격모드가 아니라면, 이는 var x 가 되어야 하나요,
// obj.x 가 되어야 하나요?
// 일반적으로는 코드를 실행하지 않고 이를 말하는 것은 불가하므로,
// 이름을 최적화 할 수 없습니다.
x;
}
</pre>
<p>이름이 짧은 변수에 객체를 할당한 후, 변수에 해당하는 프로퍼티에 접근하는 간단한 대안은 <code>with</code> 를 대체할 준비가 되었습니다.</p>
<p>둘째로, <a class="external" href="http://whereswalden.com/2011/01/10/new-es5-strict-mode-support-new-vars-created-by-strict-mode-eval-code-are-local-to-that-code-only/">엄격모드 코드의 <code>eval</code> 은 새로운 변수를 주위 스코프에 추가하지 않습니다</a>. 일반적인 코드에서 <font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">eval("var x;")</span></font> 는 변수 <code>x</code> 를 주위 함수나 전역 스코프에 추가합니다. 이는, 일반적으로 <code>eval</code> 호출을 포함하는 함수에서 인수나 지역 변수를 참조하지 않는 모든 이름은 런타임에 특정 정의에 반드시 매핑되어야 함을 의미합니다(<code>eval</code> 이 외부 변수를 숨기는 새로운 변수를 추가했기 때문입니다). 엄격모드에서 <code>eval</code> 은 evaluated 된 코드에서만 변수를 생성하므로, 외부 변수나 일부 로컬 변수에 참조하는지에 영향을 주지 않습니다.</p>
<pre class="brush: js notranslate">var x = 17;
var evalX = eval("'use strict'; var x = 42; x");
console.assert(x === 17);
console.assert(evalX === 42);
</pre>
<p>이와 관련해서, <code>eval</code> 함수가 엄격모드 코드 내에서 <code>eval(...)</code> 형태의 표현으로 적용되었다면, 코드는 엄격모드 코드로 evaluated 됩니다. 코드는 명시적으로 엄격모드를 적용할 수 있지만, 필수적인 것은 아닙니다.</p>
<pre class="brush: js notranslate">function strict1(str){
"use strict";
return eval(str); // str 은 엄격모드 코드로 다뤄짐
}
function strict2(f, str){
"use strict";
return f(str); // eval(...) 이 아님:
// str 은 엄격모드를 적용한 경우에만 엄격함
}
function nonstrict(str){
return eval(str); // str 은 엄격모드를 적용한 경우에만 엄격함
}
strict1("'엄격모드 코드!'");
strict1("'use strict'; '엄격모드 코드!'");
strict2(eval, "'느슨한 코드.'");
strict2(eval, "'use strict'; '엄격모드 코드!'");
nonstrict("'느슨한 코드.'");
nonstrict("'use strict'; '엄격모드 코드!'");
</pre>
<p>따라서 엄격모드 <code>eval</code> 코드 내의 이름은 엄격모드 코드 내의 이름이 <code>eval</code> 의 결과로 evaluated 되지 않은 것과 동일하게 동작합니다.</p>
<p>셋째로, 엄격모드는 일반 이름을 제거하는 것을 금지합니다. 엄격 모드에서 <code>delete name</code> 은 구문 에러입니다.</p>
<pre class="brush: js notranslate">"use strict";
var x;
delete x; // !!! 구문 에러
eval("var y; delete y;"); // !!! syntax error</pre>
<h3 id="eval_과_arguments_를_더_간단하게_하기"><code>eval</code> 과 <code>arguments</code> 를 더 간단하게 하기</h3>
<p>엄격모드는 <code>arguments</code> 와 <code>evel</code> 을 덜 기괴하고 마법적으로 만듭니다. 둘은 일반 코드에서 상당히 많은 마법적인 동작들을 갖고 있습니다: 바인딩을 추가하거나 삭제하고 바인딩 값을 변경하기위한 <code>eval</code>, 명명된 인수를 앨리어스하는 인덱싱된 프로퍼티 <code>arguments</code>. 엄격모드는 ECMAScript 의 미래 버전까지는 모든 수정이 이루지지는 않겠지만 <code>eval</code> 과 <code>arguments</code> 를 키워드로 다루기 위한 훌륭한 큰 걸음을 내딛었습니다.</p>
<p>첫째로, 변수명 eval 과 arguments 는 언어 문법에 바운드되거나 할당될 수 없습니다. 다음 시도들은 모두 구문 에러입니다.</p>
<pre class="brush: js notranslate">"use strict";
eval = 17;
arguments++;
++eval;
var obj = { set p(arguments) { } };
var eval;
try { } catch (arguments) { }
function x(eval) { }
function arguments() { }
var y = function eval() { };
var f = new Function("arguments", "'use strict'; return 17;");
</pre>
<p>둘째로, 엄격모드 코드는 <code>arguments</code> 객체가 생성한 프로퍼티를 앨리어스하지 않습니다. 함수의 첫 번째 인수가 <code>arg</code> 인 일반 코드에서는 <code>arg</code> 를 설정하는 것은 <code>arguments[0]</code> 를 설정하기도 하며, 그 반대도 그렇습니다(인수가 제공되지 않거나, <code>arguments[0]</code> 이 삭제된 경우는 제외). 엄격모드 함수의 <code>arguments</code> 객체는 함수가 호출될 때 원본 인수들을 저장합니다. <code><em>arguments[i]</em></code> 는 명명된 인수에 해당하는 값을 추적하지 않으며, 명명된 인수도 <code>arguments[i]</code> 에 해당하는 값을 추적하지 않습니다.</p>
<pre class="brush: js notranslate">function f(a){
"use strict";
a = 42;
return [a, arguments[0]];
}
var pair = f(17);
console.assert(pair[0] === 42);
console.assert(pair[1] === 17);
</pre>
<p>셋째로, <code>arguments.callee</code> 는 더 이상 지원되지 않습니다. 일반 코드의 <code>arguments.callee</code> 는 바깥 함수를 참조합니다. 이런 유즈 케이스는 중요하지 않습니다. 간단히 바깥 함수의 이름을 사용하면됩니다. 더욱이, <code>arguments.callee</code> 는 인라인 함수와 같은 최적화를 상당히 방해하므로, <code>arguments.callee</code> 가 접근하는 함수는 인라인이 아닌 함수를 참조하도록 제공해야 했습니다. 엄격모드 함수의 <code>arguments.callee</code> 는 삭제할 수 없는 프로퍼티이며, 설정이나 반환할때 에러를 발생합니다.</p>
<pre class="brush: js notranslate">"use strict";
var f = function() { return arguments.callee; };
f(); // TypeError
</pre>
<h3 id="JavaScript_보안">JavaScript "보안"</h3>
<p>엄격모드는 "보안된" 자바스크립트를 작성하기 쉽게 해줍니다. 일부 웹사이트들은 사용자가 다른 사용자들을 대신하여 웹사이트에서 실행시키는자바스크립트를 작성하는 방법을 제공합니다. 브라우저에서 자바스크립트는 사용자의 개인정보에 접근할수 있기 때문에, 자바스크립트는 금지된 기능에 대한 검열을 하기위해 반드시 실행전에 부분적으로 변경되어야 합니다. 자바스크립트의 유연성으로 인해 많은 런타임 체크없이 이것을 수행하는것은 사실상 불가능합니다. 특정 언어의 기능들이 너무 광범위하여 런타임 검사 수행은 상당한 성능비용이 생깁니다. 엄격모드의 작은 수정과 사용자가 제출한 자바스크립트가 엄격모드가 되면 특정 방식으로 호출되므로 런타임 검사의 필요성이 크게 줄어 듭니다. </p>
<p>첫째, 엄격모드에서는 <code>this</code> 로 함수에 전달된 값은 강제로 객체가 되지 않습니다 (a.k.a. "boxed"). 보통 함수의 경우, <code>this</code> 는 언제나 객체입니다: 객체값 <code>this</code> 와 함께 호출된 경우 제공된 객체이거나 ; 부울값, 문자 또는 숫자 <code>this</code> 로 호출된 경우 그 값은 Boxed 입니다; 또는 <code>undefined</code> 또는 <code>null</code> <code>this</code> 로 호출되면 전역객체입니다. (특정된 <code>this</code> 명세를 위해서는 <a href="/en-US/Web/JavaScript/Reference/Global_Objects/Function/call" title="en-US/JavaScript/Reference/Global_Objects/Function/call"><code>call</code></a>, <a href="/en-US/Web/JavaScript/Reference/Global_Objects/Function/apply" title="en-US/JavaScript/Reference/Global_Objects/Function/apply"><code>apply</code></a>, 또는 <a href="/en-US/Web/JavaScript/Reference/Global_Objects/Function/bind" title="en-US/JavaScript/Reference/Global_Objects/Function/bind"><code>bind</code></a> 를 사용하십시요) 자동 박싱은 성능 비용뿐 아니라 전역 객체가 브라우저에 노출되는것은 보안상 위험합니다. 전역객체들은 자바스크립트 환경의 "보안" 기능에 접근하는것을 제공하기때문에 제한되어야 합니다. 따라서 엄격모드의 함수는, 정의된 <code>this</code> 는 박스드 객체가 되지 않으며, 정의되지 않은경우 <code>this</code> 는 <code>undefined</code> 가 됩니다:</p>
<pre class="brush: js notranslate">"use strict";
function fun() { return this; }
console.assert(fun() === undefined);
console.assert(fun.call(2) === 2);
console.assert(fun.apply(null) === null);
console.assert(fun.call(undefined) === undefined);
console.assert(fun.bind(true)() === true);
</pre>
<p>즉, 브라우저에서 엄격모드의 함수내 에서는 더 이상 <code>window</code> 객체를 <code>this</code> 를 통해 참조할 수 없습니다.</p>
<p>둘째로, 엄격모드에서는 ECMAScript의 일반적으로 구현된 확장을 통해 자바스크립트 스택을 "걷는"것이 불가능합니다. 이러한 일반적인 확장 코드는, 함수 <code>fun</code> 이 호출되는 중간에, <code>fun.caller</code> 는 가장 최근에 <code>fun</code> 을 호출한 함수이고 <code>fun.arguments</code> 는 <code>fun</code>을 호출하기 위한 <code>인</code><font face="consolas, Liberation Mono, courier, monospace"><span style="background-color: rgba(220, 220, 220, 0.5);">수</span></font> 입니다. "권한있는"함수와 (잠재적으로 보안되지 않은) 인수에 접근을 허용하기때문에 두가지 확장 모두 자바스크립트의 "보안" 문제가 됩니다. <code>fun</code> 이 엄격모드인경우, both <code>fun.caller</code> 와 <code>fun.arguments</code> 모두 설정 또는 검색될때 삭제 불가능한 속성이 됩니다.</p>
<pre class="brush: js notranslate">function restricted()
{
"use strict";
restricted.caller; // throws a TypeError
restricted.arguments; // throws a TypeError
}
function privilegedInvoker()
{
return restricted();
}
privilegedInvoker();
</pre>
<p>셋째, 엄격모드의 <code>인수</code> 는 더이상 해당 함수의 호출 변수에 대한 접근을 제공하지 않습니다. 일부 이전 ECMAScript에서 <code>arguments.caller</code> 해당 함수에 별명이 지정된 객체였습니다. 이것은 함수의 추상화를 통해 권한이 있는 값을 숨길수 있는 기능을 차단하여 <a class="external" href="http://stuff.mit.edu/iap/2008/facebook/">보안의 위협</a>이 됩니다; 이것은 또한 대부분의 최적화를 배제시킵니다. 이러한 이유로 최신 브라우저들은 이를 구현하지 않습니다. 하지만 이것들의 이전 기능들 때문에, 엄격모드함수에서 <code>arguments.caller</code> 설정이나 검색시 삭제 불가능한 요소가 됩니다:</p>
<pre class="brush: js notranslate">"use strict";
function fun(a, b)
{
"use strict";
var v = 12;
return arguments.caller; //TypeError 가 발생.
}
fun(1, 2); // doesn't expose v (or a or b)
</pre>
<h3 id="미래의_ECMAScript_버전을_위한_준비">미래의 ECMAScript 버전을 위한 준비</h3>
<p>새롭게 선보일 ECMAScript 버전은 새로운 구문을 소개할 것이고, ECMAScript5에서의 엄격 모드는 변환을 쉽게 하기 위해 몇 가지의 제한을 적용할 것으로 예상되고 있습니다. 만약 이 변화들이 엄격 모드에서의 제한을 기반으로 한다면, 더 바꾸기 쉬워질 것입니다.</p>
<p>첫번째로, 엄격 모드에서의 식별자 후보들은 예약어가 됩니다. 이 예약어들은 <code>implements</code>, <code>interface</code>, <code>let</code>, <code>package</code>, <code>private</code>, <code>protected</code>, <code>public</code>, <code>static</code>, <code>yield</code>입니다. 그럼, 엄격 모드에서는 이 예약어와 똑같은 이름을 사용하거나, 변수명 또는 아규먼트명으로도 사용할 수 없습니다. </p>
<pre class="brush: js notranslate">function package(protected){ // !!!
"use strict";
var implements; // !!!
interface: // !!!
while (true){
break interface; // !!!
}
function private() { } // !!!
}
function fun(static) { 'use strict'; } // !!!
</pre>
<p>Mozilla의 특별 지시 두 가지 : 먼저, 코드가 JavaScript 1.7 또는 그보다 높고 (예를 들어, 크롬 코드 또는 <code><script type=""></code> 를 바로 사용할 때) 엄격 모드의 코드라면, <code>let</code> 와 <code>yield</code>는 처음 소개되었을 때의 그 기능을 가진다. 그러나 웹에서의 엄격 모드 코드는, <code><script src=""></code>나 <code><script>...</script></code>로 로딩되지, <code>let</code>/<code>yield</code>를 식별자로 사용할 수가 없을 것이다. 그리고 나서는, ES5 가 <code>class</code>, <code>enum</code>, <code>export</code>, <code>extends</code>, <code>import</code>, and <code>super</code> 와 같은 예약어들을 무조건 리저브함에도 불구하고, 먼저 Firefox 5 Mozilla 는 그것들을 엄격 모드에서만 리저브한다.</p>
<p>다음은, 엄격 모드는 스크립트나 함수의 탑 레벨이 아닌 곳에서의 함수 내용 정의를 제한합니다. (<a class="external" href="http://whereswalden.com/2011/01/24/new-es5-strict-mode-requirement-function-statements-not-at-top-level-of-a-program-or-function-are-prohibited/">strict mode prohibits function statements not at the top level of a script or function</a>). 브라우저에서 일반적인 코드는 함수 내용 정의가 "어디에서든" 허용됩니다. <em>이것은 ES5의 부분이 아닙니다!(심지어 ES3도 아니다.) </em>이건 다른 브라우저에서 공존할 수 없는 시멘틱의 확장입니다. 앞으로의 ECMAScript 에디션은 바라건대, 스크립트나 함수의 탑 레벨이 아닌 곳에서의 함수 내용 정의를 위해, 새로운 시멘틱을 명시할 것입니다. 엄격 모드에서 이러한 함수 정의를 금지하는 것(<a class="external" href="http://wiki.ecmascript.org/doku.php?id=conventions:no_non_standard_strict_decls">Prohibiting such function statements in strict mode</a>)은 앞으로 출시될 ECMAScript의 사양을 위한 "준비"입니다. :</p>
<pre class="brush: js notranslate">"use strict";
if (true){
function f() { } // !!! syntax error
f();
}
for (var i = 0; i < 5; i++){
function f2() { } // !!! syntax error
f2();
}
function baz(){ // kosher
function eit() { } // also kosher
}
</pre>
<p>이 규제는 엄밀히 말하면 엄격 모드가 아닌데, 저런 함수 표현식들은 기본 ECMAScript5의 확장이기 때문입니다. 그러나 이것이 ECMAScript 협회가 권장하는 방식이며, 브라우저들이 이를 지원할 것입니다. </p>
<h2 id="브라우저에서의_엄격_모드">브라우저에서의 엄격 모드</h2>
<p>현재 주류의 브라우저들은 엄격 모드를 지원하고 있습니다. 하지만, 아직도 현실에서 사용되는 수 많은 브라우저의 버전들은 엄격 모드를 부분적으로만 지원하거나(<a href="http://caniuse.com/use-strict" rel="external" title="caniuse.com availability of strict mode">Browser versions used in the wild that only have partial support for strict mode</a>), 아예 지원을 하지 않고 있기 때문에, 맹목적으로 여기에 의지할 수는 없습니다. (예를 들면, Internet Explorer 10 버전 이하!) <em>엄격 모드는 시멘틱을 바꿉니다. </em>이 변화들에 의지하는 것은 실수와 엄격 모드를 지원하지 않는 브라우저의 에러를 야기할 것입니다. 엄격 모드를 사용하는 데에 주의하는 것을 익히세요, 그리고 피쳐 테스트로 엄격 모드를 사용하기에 적절한 부분인지 확인하고 보완하세요. 마지막으로, <em>엄격 모드를 지원하는 브라우저와 그렇지 않은 브라우저에서 작성한 코드의 테스트를 확실히 하도록 하세요.</em> </p>
<h2 id="명세">명세</h2>
<table class="standard-table">
<tbody>
<tr>
<th scope="col">Specification</th>
<th scope="col">Status</th>
<th scope="col">Comment</th>
</tr>
<tr>
<td>{{SpecName('ES5.1', '#sec-10.1.1', 'Strict Mode Code')}}</td>
<td>{{Spec2('ES5.1')}}</td>
<td>초기 정의. 참조 : <a href="http://www.ecma-international.org/ecma-262/5.1/#sec-C">Strict mode restriction and exceptions</a></td>
</tr>
<tr>
<td>{{SpecName('ES6', '#sec-strict-mode-code', 'Strict Mode Code')}}</td>
<td>{{Spec2('ES6')}}</td>
<td><a href="http://www.ecma-international.org/ecma-262/6.0/#sec-strict-mode-of-ecmascript">Strict mode restriction and exceptions</a></td>
</tr>
<tr>
<td>{{SpecName('ESDraft', '#sec-strict-mode-code', 'Strict Mode Code')}}</td>
<td>{{Spec2('ESDraft')}}</td>
<td><a href="https://tc39.github.io/ecma262/#sec-strict-mode-of-ecmascript">Strict mode restriction and exceptions</a></td>
</tr>
</tbody>
</table>
<h2 id="함께_보기">함께 보기</h2>
<ul>
<li><a class="external" href="http://whereswalden.com/2010/09/08/new-es5-strict-mode-support-now-with-poison-pills/">Where's Walden? » New ES5 strict mode support: now with poison pills!</a></li>
<li><a class="external" href="http://whereswalden.com/2011/01/24/new-es5-strict-mode-requirement-function-statements-not-at-top-level-of-a-program-or-function-are-prohibited/">Where's Walden? » New ES5 strict mode requirement: function statements not at top level of a program or function are prohibited</a></li>
<li><a class="external" href="http://whereswalden.com/2011/01/10/new-es5-strict-mode-support-new-vars-created-by-strict-mode-eval-code-are-local-to-that-code-only/">Where's Walden? » New ES5 strict mode support: new vars created by strict mode eval code are local to that code only</a></li>
<li><a href="http://qnimate.com/javascript-strict-mode-in-nutshell/">JavaScript "use strict" tutorial for beginners.</a></li>
<li><a class="external" href="http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/">John Resig - ECMAScript 5 Strict Mode, JSON, and More</a></li>
<li><a class="external" href="http://dmitrysoshnikov.com/ecmascript/es5-chapter-2-strict-mode/">ECMA-262-5 in detail. Chapter 2. Strict Mode.</a></li>
<li><a class="external" href="http://kangax.github.io/compat-table/es5/#Strict_mode">Strict mode compatibility table</a></li>
<li><a href="/en-US/docs/Web/JavaScript/Reference/Strict_mode/Transitioning_to_strict_mode">Transitioning to strict mode</a></li>
</ul>
|