aboutsummaryrefslogtreecommitdiff
path: root/files/de/web/javascript/reference/strict_mode/index.html
blob: e0ee3c9c151bc813b21bf86942f3fc9d8a9a5fc0 (plain)
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
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
---
title: Strict mode
slug: Web/JavaScript/Reference/Strict_mode
tags:
  - ECMAScript5
  - JavaScript
  - NeedsTranslation
  - Strict Mode
  - TopicStub
translation_of: Web/JavaScript/Reference/Strict_mode
---
<div>{{JsSidebar("More")}}</div>

<div class="callout-box">Der normale, nicht-strikte Modus wird manchmal auch <strong>"{{Glossary("Sloppy Mode")}}"</strong> (schlampiger Modus) genannt. Das ist zwar keine offizielle Bezeichnung, aber behalten Sie das für den Fall der Fälle im Hinterkopf.</div>

<p>Der in ECMAScript 5 eingeführte strikte Modus von JavaScript ist eine Möglichkeit, sich für eine eingeschränkte Variante von JavaScript zu entscheiden, wodurch der "{{Glossary("Sloppy Mode")}}" implizit deaktiviert wird. Der strikte Modus ist nicht nur eine Teilmenge: Er hat absichtlich eine andere Semantik als normaler Code. Browser, die den strikten Modus nicht unterstützen, führen Code im strikten Modus anders aus, als Browser, die ihn unterstützen. Verlassen Sie sich daher nicht auf den strikten Modus, ohne vorher die relevanten Aspekte des strikten Modus zu testen. Code im strikten Modus und Code im nicht-strikten Modus können beidermaßen vorhanden sein, sodass Skripte nach und nach in den strikten Modus überführt werden können.</p>

<p><span class="tlid-translation translation"><span title="">Der strikte Modus nimmt einige Änderungen an der normalen JavaScript-Semantik vor:</span></span></p>

<ol>
 <li>Bisher still ignorierte Fehler führen zum Skriptabbruch.</li>
 <li>Behebt Fehler, die Optimierungen durch JavaScript-Interpreter erschweren oder verhindern. Code im strikten Modus kann manchmal schneller ausgeführt werden als identischer Code im nicht-strikten Modus.</li>
 <li>Verbietet Syntax, die in zukünftigen Versionen von ECMAScript wahrscheinlich definiert wird.</li>
</ol>

<p>Siehe <a href="/de/docs/Web/JavaScript/Reference/Strict_mode/wechsel_zum_strict_mode">Wechsel zum Strict Mode</a>, falls Ihr Code im eingeschränken Modus von JavaScript funktionieren soll.</p>

<h2 id="In_den_strikten_Modus_schalten">In den strikten Modus schalten</h2>

<p>Der strikte Modus gilt entweder für <em>ganze Skripte</em> oder <em>einzelne Funktionen</em>. Er kann nicht auf einen Anweisungsblock innerhalb geschweifter Klammern <code>{}</code> angewendet werden; bei einem solchen Versuch wird nichts passieren. Code, der an <code>eval</code>, <code>Function</code> oder Event-Handler-Attribute übergeben wird, sowie an {{domxref("WindowTimers.setTimeout()")}} übergebene Strings und dergleichen sind ganze Skripte, in denen das Einschalten des strikten Modus wie erwartet funktioniert.</p>

<h3 id="Strikter_Modus_für_Skripte">Strikter Modus für Skripte</h3>

<p>Um ein ganzes Skript in den strikten Modus zu schalten geben Sie <em>genau</em> die Anweisung <code>"use strict";</code> (oder <code>'use strict';</code>) als <em>erste</em> Anweisung, noch vor allen anderen Anweisungen an.</p>

<pre class="brush: js">// Strikter Modus für komplettes Skript
'use strict';
var v = 'Hi!  Ich bin ein Skript im strikten Modus!';
</pre>

<p>Diese Syntax hat eine Falle, in die <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=579119">bereits auch</a> eine <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=627531">große Seite</a> getappt ist: Mehrere Skript-Dateien können nicht einfach aneinander gehängt werden.<br>
 Wird ein Skript B, das im strikten Modus laufen soll, an ein Skript A, das nicht im strikten Modus laufen soll, angehängt, erscheint das <code>"use strict";</code> des angehängtes Skriptes B de facto in der Mitte der zusammengeführten Datei AB und wird folglich vom Interpreter ignoriert.<br>
 Ebenso wird im umgekehrten Fall ein eigentlich nicht-striktes Skript, das an ein striktes angehängt wurde, auch im vom ersten Skript gewünschten strikten Modus ausgeführt werden.</p>

<p>Die Verkettung von Skripten ist im Grunde nie ratsam, falls es aber nicht anders geht, ziehen Sie in Betracht den strikten Modus immer nur für einzelne Funktionen zu aktivieren.<br>
 Sie können auch den gesamten Inhalt eines Skripts in eine selbstausführende, anonyme Funktion einschließen und für diese den gewünschten Modus festlegen. Dadurch wird das Verkettungsproblem beseitigt, und Sie müssen alle gemeinsam genutzten Variablen explizit aus dem Geltungsbereich der Funktion exportieren.</p>

<h3 id="Strikter_Modus_für_Funktionen">Strikter Modus für Funktionen</h3>

<p>Um eine Funktion in den strikten Modus zu schalten geben Sie <em>genau</em> die Anweisung <code>"use strict";</code> (oder <code>'use strict';</code>) im Rumpf der Funktion als <em>erste</em> Anweisung an, vor allen anderen.</p>

<pre class="brush: js">function strict(){
  // Syntac im strikten Modus auf Funktions-Ebene
  'use strict';
  function nested() { return 'Und ich auch!'; }
  return 'Hi! Ich bin eine Funktion im strikten Modus! ' + nested();
}
function notStrict() { return 'Ich bin nicht strikt.'; }
</pre>

<h3 id="Strikter_Modus_für_Module">Strikter Modus für Module</h3>

<p>In ECMAScript 2015 wurden JavaScript-Module eingeführt und damit eine weitere Möglichkeit, in den strikten Modus zu schalten. Der gesamte Inhalt von JavaScript-Modulen wird per Definition im strikten Modus ausgeführt, ein ausdrückliches Einschalten ist nicht nötig.</p>

<pre class="brush: js">function strict() {
    // da ich ein Modul bin, bin ich standardmäßig strikt
}
export default strict;</pre>

<h2 id="Änderungen_im_strikten_Modus">Änderungen im strikten Modus</h2>

<p>Der strikte Modus ändert sowohl die Syntax als auch das Laufzeitverhalten. Änderungen fallen im Allgemeinen in folgende Kategorien:</p>

<ul>
 <li>Änderungen, die Versehen in Fehler umwandeln (als Syntaxfehler oder zur Laufzeit)</li>
 <li>Änderungen, die die Berechnung der jeweiligen Variablen für eine bestimmte Verwendung eines Namens vereinfachen</li>
 <li>Änderungen, die <code>eval</code> und <code>arguments</code> vereinfachen</li>
 <li>Änderungen, die das Schreiben von "sicherem" JavaScript erleichtern und</li>
 <li>Änderungen, die zukünftige ECMAScript-Entwicklungen vorwegnehmen.</li>
</ul>

<h3 id="Versehen_in_Fehler_umwandeln">Versehen in Fehler umwandeln</h3>

<p>Der strikte Modus wandelt einige zuvor still akzeptierte Versehen in ausdrückliche Fehler um. JavaScript wurde konzipiert, um Anfängern den Einstieg zu erleichtern und ignoriert Operationen, die eigentlich Fehler sind, stillschweigend. Manchmal wird dadurch das unmittelbare Problem behoben, das kann später jedoch größeren Problemen führen. Der strikte Modus behandelt diese Versehen als Fehler, so dass sie entdeckt und unverzüglich behoben werden können.</p>

<p>Erstens ist es im strikten Modus nicht mehr möglich, versehentlich eine globale Variable zu erstellen. Vertippt man sich bei einer Zuweisung einer Variable in normalem JavaScript wird eine neue Eigenschaft im globalen Objekt erstellt und alles "funktioniert" noch (es kann in Zukunft jedoch trotzdem schiefgehen: wahrscheinlich in modernem JavaScript). Im strikten Modus lösen Zuweisungen, die versehentlich globale Variablen erzeugen würden, einen Fehler aus:</p>

<pre class="brush: js">'use strict';
                     // Angenommen eine globale Variable mit dem Namen
vertipeVaiable = 17; // vertippteVariable existiert, verursacht diese Zeile einen
                     // ReferenceError, weil die Variable falsch geschrieben wurde
</pre>

<p>Zweitens löst der strikte Modus bei Zuweisungen, die sonst im Stillen fehlschlagen, eine Exception aus. <code>NaN</code> ist beispielsweise eine nicht beschreibbare globale Variable. Bei normalem Code passiert bei der Zuweisung zu <code>NaN</code> nichts weiter, insbesondere wird keine Fehlermeldung ausgegeben. Im strikten Modus löst die Zuweisung an <code>NaN</code> eine Exception aus. Jede Zuweisung, die im normalen Code unbemerkt fehlschlägt (Zuweisung an ein nicht beschreibbares globales Objekt oder an eine Eigenschaft, Zuweisung an eine Eigenschaft die nur einen Getter hat, Zuweisung an eine neue Eigenschaft eines nicht-existierenden Objekts), löst im strikten Modus eine Exception aus:</p>

<pre class="brush: js">'use strict';

// Zuweisung an ein nicht-beschreibbares, globales Objekt
var undefined = 5; // verursacht TypeError
var Infinity = 5; // verursacht TypeError

// Zuweisung an eine nicht-beschreibbare Eigenschaft
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // verursacht TypeError

// Zuweisung an eine Eigenschaft, die nur einen Getter hat
var obj2 = { get x() { return 17; } };
obj2.x = 5; // verursacht TypeError

// Zuweisung einer neuen Eigenschaft an ein nicht-erweiterbares Objekt
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // verursacht TypeError</pre>

<p>Drittens löst der strikte Modus beim Versuch unlöschbare Eigenschaften zu löschen ebenfalls eine Exception aus:</p>

<pre class="brush: js">'use strict';
delete Object.prototype; // verursacht TypeError
</pre>

<p>Viertens erforderte der strikte Modus bis ECMAScript 2015 (vor Gecko 34), dass alle in einem Objekt-Literal aufgeführten Eigenschaften eindeutig definiert werden. Normaler Code kann Eigenschaften mehrfach definieren, wobei die letzte Definition den Wert der Eigenschaft bestimmt.</p>

<div class="note">
<p>Dies ist seit ECMAScript 2015 nicht mehr der Fall ({{bug(1041128)}}).</p>
</div>

<pre class="brush: js">'use strict';
var o = { p: 1, p: 2 }; // !!! Syntaxfehler
</pre>

<p>Fünftens erfordert der strikte Modus, dass die Namen der Funktionsparameter eindeutig sind. Im normalen Code verbirgt das letzte duplizierte Argument vorherige gleichnamige Argumente. Diese vorherigen Argumente sind weiterhin durch <code>arguments[i]</code> verfügbar, sodass sie nicht gänzlich unzugänglich sind. Dieses Verstecken ist jedoch wenig sinnvoll und wahrscheinlich unerwünscht (z. B. bei einem Tippfehler), sodass im strikten Modus doppelte Argumentnamen einen Syntaxfehler darstellen:</p>

<pre class="brush: js">function sum(a, a, c) { // !!! Syntaxfehler
  'use strict';
  return a + a + c; // falsch, wenn dieser Code ausgeführt würde
}
</pre>

<p>Sechstens verbietet der strikte Modus seit ECMAScript 5 die allein führende Null als Syntax für Oktalzahlen, zum Beispiel ist <code>0644 === 420</code> oder <code>"\ 045" === "%"</code>. Diese oktale Syntax ist nicht Teil von ECMAScript 5, wird jedoch von allen Browsern unterstützt. In ECMAScript 2015 werden oktalen Zahlen stattdessen die Zeichen <code>0o</code> vorangestellt:</p>

<pre class="brush: js">var a = 0o10; // ES2015: Octal
</pre>

<p>Anfänger glauben manchmal, dass führende Nullen entsprechend der landläufigen Nutzung des Dezimalsystems keine semantische Bedeutung für den Wert der Zahl an sich hat – und verwenden sie zur Ausrichtung. Dies führt in Javascript jedoch unweigerlich zum Wechsel vom Dezimal- in das Oktalsystem und ergibt mithin einen völlig anderen Wert! Daher sind führende Nullen im strikten Modus ein Syntaxfehler:</p>

<pre class="brush: js">'use strict';
var sum = 015 + // !!! Syntaxfehler
          197 +
          142;

var sumWithOctal = 0o10 + 8;
console.log(sumWithOctal); // 16
</pre>

<p>Siebtens verbietet der strikte Modus in ECMAScript 2015 das Zuweisen von Eigenschaften an {{Glossary("primitive")}} Werte. Ohne den strikten Modus wird das einfach ignoriert (no-op), mit dem strikten Modus wird jedoch ein {{jsxref("TypeError")}} ausgelöst.</p>

<pre class="brush: js">(function() {
'use strict';

false.true = '';         // TypeError
(14).sailing = 'home';   // TypeError
'with'.you = 'far away'; // TypeError

})();
</pre>

<h3 id="Vereinfachung_der_Verwendung_von_Variablen">Vereinfachung der Verwendung von Variablen</h3>

<p>Der strikte Modus vereinfacht die Zuordnung von Variablennamen zu bestimmten Variablendefinitionen im Code. Viele Compiler-Optimierungen setzen voraus, dass die Variable <em>X</em> an <em>diesem</em> Ort gespeichert wird. Dies ist für die vollständige Optimierung von JavaScript-Code von entscheidender Bedeutung. JavaScript macht es manchmal unmöglich, diese grundlegende Zuordnung von Name zu Variablendefinition im Code bis zur Laufzeit durchzuführen. Der strikte Modus entfernt die meisten Fälle, in denen dies geschieht, sodass der Compiler den Code im strikten Modus besser optimieren kann.</p>

<p>Erstens verbietet der strikte Modus <code>with</code>. Das Problem bei <code>with</code> ist, dass ein beliebiger Name innerhalb des Blocks entweder</p>

<ul>
 <li>einer Eigenschaft des übergebenen Objekts oder</li>
 <li>einer Variablen im umgebenden (oder sogar globalen) Gültigkeitsbereich zur Laufzeit zugeordnet werden kann</li>
</ul>

<p>Es ist unmöglich vorher zu wissen, welcher Fall eintritt. Der strikte Modus macht aus <code>with</code> einen Syntaxfehler, sodass keine Möglichkeit besteht, dass ein Name innerhalb von <code>with</code> zur Laufzeit auf einen unbekannten Ort verweist:</p>

<pre class="brush: js">'use strict';
var x = 17;
with (obj) { // !!! Syntaxfehler
  // Wenn dies nicht der strikte Modus wäre, wäre dies var x
  // oder wäre es stattdessen obj.x? Es ist im Allgemeinen unmöglich,
  // dies ohne Ausführen des Codes vorherzusagen, daher kann der Name
  // nicht optimiert werden.
  x;
}
</pre>

<p>Die simple Alternative, ein Objekt einer Variablen mit kurzem Namen zuzuweisen, um dann auf die entsprechende Eigenschaft dieser Variable zuzugreifen, macht <code>with</code> überflüssig.</p>

<p>Zweitens führt <a href="https://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> im strikten Modus keine neuen Variablen in den umgebenden Geltungsbereich ein</a>. In normalem Code fügt <code>eval("var x;")</code> eine Variable <code>x</code> in die umgebende Funktion oder den globalen Gültigkeitsbereich ein. Das bedeutet im Allgemeinen, dass in einer Funktion, die einen <code>eval</code>-Aufruf enthält, jeder Name, der sich nicht auf ein Argument oder eine lokale Variable bezieht, zur Laufzeit einer bestimmten Definition zugeordnet werden muss (da <code>eval</code> eine neue Variable eingeführt haben könnte, die die äußere Variable verbirgt). Im strikten Modus erstellt <code>eval</code> nur Variablen für den auszuwertenden Code. Daher kann <code>eval</code> nicht beeinflussen, ob ein Name auf eine äußere oder eine lokale Variable verweist:</p>

<pre class="brush: js">var x = 17;
var evalX = eval("'use strict'; var x = 42; x;");
console.assert(x === 17);
console.assert(evalX === 42);
</pre>

<p>Wenn die Funktion <code>eval</code> von einem Ausdruck der Form <code>eval(...)</code> in Code im strikten Modus aufgerufen wird, wird der Code ebenfalls im strikten Modus ausgewertet. Der Code kann zwar explizit den strikten Modus aufrufen, dies ist jedoch überflüssig.</p>

<pre class="brush: js">function strict1(str) {
  'use strict';
  return eval(str); // str wird als Code im strikten Modus betrachtet
}
function strict2(f, str) {
  'use strict';
  return f(str); // kein eval(...): str ist nur dann strikt wenn
                 // es den strikten Modus aufruft
}
function nonstrict(str) {
  return eval(str); // str ist nur dann strikt wenn
                    // es den strikten Modus aufruft
}

strict1("'Code im strikten Modus!'");
strict1("'use strict'; 'Code im strikten Modus!'");
strict2(eval, "'Code im nicht-strikten Modus.'");
strict2(eval, "'use strict'; 'Code im strikten Modus!'");
nonstrict("'Code im nicht-strikten Modus.'");
nonstrict("'use strict'; 'Code im strikten Modus!'");
</pre>

<p>Daher verhalten sich Namen in <code>eval</code>-Code im strikten Modus identisch zu solchen die in regulärem Code im strikten Modus geschrieben wurden, welche kein Ergebnis eines <code>eval</code>-Ausdrucks sind.</p>

<p>Drittens verbietet der strikte Modus das Löschen bloßer Namen. <code>delete name</code> ist im strikten Modus ein Syntaxfehler:</p>

<pre class="brush: js">'use strict';

var x;
delete x; // !!! Syntaxfehler

eval('var y; delete y;'); // !!! Syntaxfehler
</pre>

<h3 id="Vereinfachung_von_eval_und_arguments">Vereinfachung von <code>eval</code> und <code>arguments</code></h3>

<p>Der strikte Modus macht <code>arguments</code> und <code>eval</code> weniger bizarr. Beide haben in normalem Code ein erhebliches Maß an fragwürdigem Verhalten: <code>eval</code> fügt Bindungen hinzu, entfernt sie oder ändert ihre Werte, während <code>arguments</code> durch seine indizierten Eigenschaften benannten Argumenten Aliase gibt. Der strikte Modus versucht <code>eval</code> und <code>arguments</code> möglichst als Schlüsselwörter zu behandeln, obwohl vollständige Korrekturen erst in einer zukünftigen Ausgabe von ECMAScript verfügbar sein werden.</p>

<p>Erstens können eval und arguments nicht mit Sprachsyntax gebunden oder zugewiesen werden. Sämtliche Versuche dies zu tun verursachen Syntaxfehler:</p>

<pre class="brush: js">'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>Zweitens vergibt Code im strikten Modus Eigenschaften keine Aliase, die in <code>arguments</code>-Objekten erstellt wurden. In normalem Code innerhalb einer Funktion, deren erstes Argument <code>arg</code> ist, setzt das Festlegen von <code>arg</code> auch <code>arguments[0]</code> und umgekehrt (sofern keine Argumente angegeben wurden oder <code>arguments[0]</code> gelöscht wird). <code>arguments</code>-Objekte für Funktionen im strikten Modus speichern die ursprünglichen Argumente, wenn die Funktion aufgerufen wird. <code>arguments[i]</code> verfolgt weder den Wert des entsprechenden benannten Arguments, noch verfolgt ein benanntes Argument den Wert im entsprechenden <code>arguments[i]</code>.</p>

<pre class="brush: js">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>Drittens wird <code>arguments.callee</code> nicht mehr unterstützt. In normalem Code bezieht sich <code>arguments.callee</code> auf die umschließende Funktion. Dieser Anwendungsfall ist schwach: benennen Sie einfach die umschließende Funktion! <span style="">Darüber hinaus behindert <code>arguments.callee</code> Optimierungen wie das Inlining von Funktionen im Wesentlichen, da es möglich sein muss, einen Verweis auf die nicht Inline-Funktion bereitzustellen, wenn auf <code>arguments.callee</code> zugegriffen wird. <code>arguments.callee</code> für Funktionen im strikten Modus ist eine nicht löschbare Eigenschaft, die beim Zuweisen oder Abrufen eine Exception auslöst:</span></p>

<pre class="brush: js">'use strict';
var f = function() { return arguments.callee; };
f(); // verursacht TypeError
</pre>

<h3 id="JavaScript_absichern">JavaScript "absichern"</h3>

<p>Der strikte Modus erleichtert das Schreiben von "sicherem" JavaScript. Einige Websites bieten Benutzern heute die Möglichkeit, JavaScript zu schreiben, das von der Website <em>für andere Benutzer ausgeführt wird</em>. JavaScript in Browsern kann auf die privaten Informationen des Benutzers zugreifen. Daher muss JavaScript vor der Ausführung teilweise transformiert werden, um den Zugriff auf verbotene Funktionalität zu sperren. Ohne viele Laufzeitüberprüfungen macht die Flexibilität von JavaScript dies praktisch unmöglich. Bestimmte Sprachfunktionen sind so tiefgreifend, dass die Durchführung von Laufzeitüberprüfungen erhebliche Leistungseinbußen nach sich zieht. Ein paar Feinjustierungen im strikten Modus sowie die Notwendigkeit, dass vom Benutzer eingegebenes JavaScript im strikten Modus läuft und auf bestimmte Weise aufgerufen wird, reduzieren die Laufzeitprüfungen erheblich.</p>

<p>Erstens wird der als <code>this</code> übergebene Wert an eine Funktion im strikten Modus nicht zwingend zu einem Objekt (auch "boxed" genannt). Bei einer normalen Funktion ist <code>this</code> immer ein Objekt: Entweder das bereitgestellte Objekt, wenn <code>this</code> mit einem Objektwert aufgerufen wird; der boxed Wert, wenn mit <code>this</code> mit einem Boolean, einem String oder Number aufgerufen wird; oder das globale Objekt, wenn es mit einem <code>undefined</code> oder <code>null</code> <code>this</code> aufgerufen wird (verwenden Sie <a href="/de/Web/JavaScript/Reference/Global_Objects/Function/call">call</a>, <a href="/de/Web/JavaScript/Reference/Global_Objects/Function/apply">apply</a> oder <a href="/de/Web/JavaScript/Reference/Global_Objects/Function/bind">bind</a>, um ein bestimmtes zu <code>this</code> spezifizieren). Automatisches Boxing ist nicht nur mit Leistungseinbußen verbunden, es ist darüber hinaus ein Sicherheitsrisiko das globale Objekt in Browsern verfügbar zu machen, da das globale Objekt Zugriff auf Funktionen bietet, die "geschützte" JavaScript-Umgebungen einschränken müssen. Für eine Funktion im strikten Modus wird das übergebene this nicht in ein Objekt geboxed, und wenn keine Angabe erfolgt, wird <code>this</code> zu <code>undefined</code>:</p>

<pre class="brush: js">'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>Das bedeutet unter anderem, dass es in Browsern nicht mehr möglich ist, das <code>window</code>-Objekt innerhalb einer Funktion im strikten Modus durch <code>this</code> zu referenzieren.</p>

<p>Zweitens ist es im strikten Modus nicht mehr möglich, den JavaScript-Stack über allgemein implementierte Erweiterungen von ECMAScript zu "durchwandern". Ist in normalem Code eine Funktion namens <code>fun</code> mitten in der Ausführung ist <code>fun.caller</code> die Funktion die zuletzt <code>fun</code> aufgerufen hat und <code>fun.arguments</code> ist das <code>arguments</code> des Aufrufs von <code>fun</code>. Beide Erweiterungen sind für "sicheres" JavaScript problematisch, weil sie es "sicherem" Code erlauben auf "priviligierte" Funktionen und ihre (potentiell ungesicheren) argumente zuzugreifen. Wenn <code>fun</code> im strikten Modus ist, sind sowohl <code>fun.caller</code> als auch <code>fun.argument</code> nicht-löschbare Eigenschaften, die eine Exception auslösen wenn man versucht auf sie zuzugreifen:</p>

<pre class="brush: js">function restricted() {
  'use strict';
  restricted.caller;    // verursacht TypeError
  restricted.arguments; // verursacht TypeError
}
function privilegedInvoker() {
  return restricted();
}
privilegedInvoker();
</pre>

<p>Drittens gewährt arguments in Funktionen im strikten Modus keinen Zugriff mehr auf die entsprechenden Variablen des Funktionsaufrufs. In einigen ECMAScript-Implementierungen war arguments.caller ein Objekt, dessen Eigenschaften Aliase zu Funktions-Variablen darstellten. Dies ist ein <a href="https://stuff.mit.edu/iap/2008/facebook/">Sicherheitsrisiko</a>, da es die Möglichkeit priviligierte Werte durch Funktionsabstraktion auszublenden einschränkt; es schließt darüber hinaus die meisten Optimierungen aus. Aus diesen Gründen implementieren aktuellen Browser es auch nicht. Aufgrund seiner historischen Funktionalität ist <code>arguments.caller</code> jedoch für eine Funktion im strikten Modus auch eine nicht-löschbare Eigenschaft, die beim Zuweisen oder Abrufen eine Exception auslöst:</p>

<pre class="brush: js">'use strict';
function fun(a, b) {
  'use strict';
  var v = 12;
  return arguments.caller; // verursacht TypeError
}
fun(1, 2); // gibt v nicht preis (oder a oder b)
</pre>

<h3 id="Wegbereiter_für_zukünftige_ECMAScript-Versionen">Wegbereiter für zukünftige ECMAScript-Versionen</h3>

<p>Zukünftige ECMAScript-Versionen werden wahrscheinlich eine neue Syntax einführen, und der strikte Modus in ECMAScript 5 enthält einige Einschränkungen, um den Übergang zu erleichtern. Es ist einfacher, einige Änderungen vorzunehmen, wenn die Grundlagen dieser Änderungen im strikten Modus verboten sind.</p>

<p>Erstens wird im strikten Modus eine kleine Anzahl von Bezeichnern reservierte Schlüsselwörter. Diese sind <code>implements</code>, <code>interface</code>, <code>let</code>, <code>package</code>, <code>private</code>, <code>protected</code>, <code>public</code>, <code>static</code> und <code>yield</code>. Im strikten Modus können Sie daher keine Variablen oder Argumente mit diesen Namen benennen oder verwenden.</p>

<pre class="brush: js">function package(protected) { // !!!
  'use strict';
  var implements; // !!!

  interface: // !!!
  while (true) {
    break interface; // !!!
  }

  function private() { } // !!!
}
function fun(static) { 'use strict'; } // !!!
</pre>

<p>Zwei Mozilla-spezifische Vorbehalte:</p>

<ul>
 <li>Wenn Ihr Code in JavaScript 1.7 oder höher geschrieben ist (etwa, in Chrome-Code oder beim Benutzen des richtigen <code>&lt;script type=""&gt;</code>) und den strikten Modus verwendet, haben <code>let</code> und <code>yield</code> die Funktionalität, die sie seit ihrer Einführung gehabt haben. Code im strikten Modus im Web, welcher mit <code>&lt;script src=""&gt;</code> oder <code>&lt;script&gt;...&lt;/script&gt;</code> geladen wurde, kann <code>let</code>/<code>yield</code> nicht als Bezeichner verwenden.</li>
 <li>Während ES5 bedingungslos die Wörter <code>class</code>, <code>enum</code>, <code>export</code>, <code>extends</code>, <code>import</code> und <code>super</code> reserviert, reservierte Mozilla sie vor Firefox 5 nur im strikten Modus.</li>
</ul>

<p>Zweitens <a href="https://whereswalden.com/2011/01/24/new-es5-strict-mode-requirement-function-statements-not-at-top-level-of-a-program-or-function-are-prohibited/">verbietet der strikte Modus Funktionsanweisungen, die nicht auf der obersten Ebene eines Skripts oder einer Funktion stehen</a>. Im normalen Modus sind Funktionsanweisungen in Browsern "überall" zulässig. <em>Dies ist nicht Teil von ES5 (oder gar ES3)!</em> Es ist eine Erweiterung mit inkompatibler Semantik in verschiedenen Browsern. Beachten Sie, dass Funktionsanweisungen außerhalb der obersten Ebene in ES2015 zulässig sind.</p>

<pre class="brush: js">'use strict';
if (true) {
  function f() { } // !!! Syntaxfehler
  f();
}

for (var i = 0; i &lt; 5; i++) {
  function f2() { } // !!! Syntaxfehler
  f2();
}

function baz() { // koscher
  function eit() { } // ebenfalls koscher
}
</pre>

<p>Dieses Verbot ist eigentlich nicht Teil des strikten Modus, da solche Funktionsanweisungen eine Erweiterung von grundlegendem ES5 sind. Dies ist jedoch die Empfehlung des ECMAScript-Komitees und Browser werden es implementieren.</p>

<h2 id="Strikter_Modus_in_Browsern">Strikter Modus in Browsern</h2>

<p>Die wichtigsten Browser implementieren heute den strikten Modus. Verlassen Sie sich jedoch nicht blind darauf, da in freier Wildbahn immer noch <a href="https://caniuse.com/use-strict">zahlreiche Browser-Versionen verwendet werden, die den strikten Modus nur teilweise</a> oder gar nicht unterstützen (z. B. Internet Explorer vor Version 10!). <em>Strikter Modus ändert die Semantik.</em> Sich auf diese Änderungen zu verlassen, führt zu Versehen und Fehlern in Browsern, die den strikten Modus nicht implementieren. Seien Sie vorsichtig im strikten Modus und erhöhen Sie die Verlässlichkeit des strikten Modus mit Funktionstests, die prüfen, ob die für Ihren Code relevante Teile des strikten Modus implementiert sind. Testen Sie Ihren Code <em>in Browsern, die den strikten Modus unterstützen und nicht unterstützen.</em> Wenn Sie nur in Browsern testen, die den strikten Modus nicht unterstützen, bekommen Sie wahrscheinlich Probleme in Browsern, die ihn unterstützen, und umgekehrt.</p>

<h2 id="Spezifikationen">Spezifikationen</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Spezifikation</th>
   <th scope="col">Status</th>
   <th scope="col">Kommentar</th>
  </tr>
  <tr>
   <td>{{SpecName('ES5.1', '#sec-10.1.1', 'Strict Mode Code')}}</td>
   <td>{{Spec2('ES5.1')}}</td>
   <td>Erste Definition. Siehe: <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>
 </tbody>
</table>

<h2 id="Siehe_auch">Siehe auch</h2>

<ul>
 <li><a class="external" href="https://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="https://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="https://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="https://kangax.github.io/compat-table/es5/#Strict_mode">Strict mode compatibility table</a></li>
 <li><a href="/de/docs/Web/JavaScript/Reference/Strict_mode/wechsel_zum_strict_mode">Wechsel zum Strict Mode</a></li>
</ul>