use strict in JavaScript (use strict in JavaScript), Lektion, Seite 723579
https://www.purl.org/stefan_ram/pub/use_strict_javascript (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
JavaScript-Kurs

»"use strict";« in JavaScript 

Die Auswertungsanweisung »"use strict";« (oder »'use strict';«) hat den Effekt, daß sie die JavaScript -Implementation auf den strengen Modus umstellt, in dem einige fragwürdige Kommandos als Fehler abgelehnt und einige andere Kommandos eine andere Bedeutung haben werden. Die Verwendung von »"use strict";« wird empfohlen, weil sie dabei hilft, Programmierfehler zu finden.

Die use-strict-Anweisung
          .------------.          .-.
--->.--->( "use strict" )---.--->( ; )--->
| '------------' ^ '-'
| .------------. |
'--->( 'use strict' )---'
'------------'

Vorteile von »"use strict";«

Kein versehentliches Anlegen neuer Eigenschaften

Protokoll nach Neustart des Browsers
examplename = 5
5
Protokoll nach Neustart des Browsers

"use strict"; examplename = 5

ReferenceError: assignment to undeclared variable a

Eigenschaften des globalen Objekts können weiterhin mit dem expliziten »this.« angelegt werden, beispielsweise »this.examplename=5«.

Kein stilles Scheitern einer Zusweisung

Protokoll nach Neustart des Browsers
NaN = 5 /* stilles Scheitern */
5
Protokoll nach Neustart des Browsers

"use strict"; NaN = 5 /* lautes Scheitern */

TypeError: "NaN" is read-only

Kein stilles Scheitern beim Löschen

Protokoll nach Neustart des Browsers
delete this.undefined /* stilles Scheitern */
false
Protokoll nach Neustart des Browsers
"use strict"; delete this.undefined /* lautes Scheitern */
TypeError: property "undefined" is non-configurable and can't be deleted

Im strengen Modus ist nur das Löschen von Eigenschaften  erlaubt; diese müssen dazu mit einem echten Eintragsausdruck (mit einem Punkt) angegeben werden.

Protokoll nach Neustart des Browsers
a = 5
5
"use strict"; delete a;
SyntaxError: applying the 'delete' operator to an unqualified name is deprecated
"use strict"; delete this.a;
true

Schutz einiger Namen als Quasi-Schlüsselwörter

Zuweisungen an »eval« und »arguments« sind im strengen Modus nicht erlaubt. Diese werden dadurch denn Schlüsselwörtern ähnlicher als den Bezeichnern.

Protokoll nach Neustart des Browsers

eval = 2

2

"use strict"; eval = 2

im strengen Modus nicht erlaubte Namen (wie eventuelle zukünftige Schlüsselwörter oder einige Java -Schlüsselwörter)
implements interface package private protected public
sonstige Wörter, die im strengen Modus nicht als Namen verwendet werden dürfen
eval arguments

Führende Nullen

Führende Nullen bei ganzzahligen Literalen sind im strengen Modus verboten, da die versehentliche Verwendung einer führenden Null zu einem anderen als den beabsichtigten Wert führen könnte.

Auswertung
()=>{ 05; }
function ()
Auswertung
()=>{ "use strict"; 05; }
SyntaxError: "0"-prefixed octal literals and octal escape sequences are deprecated; for octal literals use the "0o" prefix instead

»"use strict";« gilt für den ihm folgenden  Teil einer Quelltexteinheit.

Protokoll
02; "use strict"; 3
3

»"use strict";« gilt nicht  für Teile anderer Quelltexteinheiten, selbst wenn diese nach »"use strict";« in einer Quelltexteinheit aufgerufen werden.

Protokoll
f = ()=> 05
function f()
"use strict"; f()
5
"use strict"; 05
SyntaxError

»"use strict";« gilt nicht   für das Laufzeitverhalten, sondern nur für den Quelltext. Daher können Numeralia in Zeichenfolgen weiterhin umgewandelt werden, auch wenn sie mit einer Null beginnen.

Protokoll
"use strict"; +"010"
10

Das globale »"use strict";«

Ein Skript wird in Quelltexteinheiten  (“[syntactic ]source text unit ”) unterteilt, die wir auch kurz Einheiten  nennen. Was eine Quelltexteinheit genau ist, hängt von der verwendeten JavaScript -Implementation ab.

Damit »"use strict";« für eine Einheit beachtet wird, muß es ganz am Anfang  jener Einheit stehen. Es stellt dann den strengen Modus für die gesamte Einheit ein. Solch ein »"use strict";« nennen wir auch ein globales  »"use strict";«.

Skript

"use strict";

/* ... */

Das lokale »"use strict";«

»"use strict";« kann auch als erste Anweisung im Block  einer Blockfunktion verwendet werden, um für jenen Block den strengen Modus zu festzulegen.

Auswertung
()=>{ "use strict"; /* ... */ }
function ()

Das »"use strict";« in »eval«

»"use strict";« kann auch als erste Anweisung in der Sequenz in einem eval-Aufruf verwendet werden, um für jene Sequenz den strengen Modus zu festzulegen. Wenn der strenge Modus bereits für die Umgebung des eval-Aufrufs eingestellt wurde, wird er nicht immer automatisch für jene Sequenz übernommen.

Auswertung
eval( "'use strict'; /* ... */" );
function ()

Stilregeln

  Stilregel Da der strenge Modus dabei hilft, Fehler zu entdecken, ist die Verwendung von »"use strict;"« empfehlenswert.

Diese Stilregel gilt aber nur für den Fall, daß »"use strict;"« in neu geschriebenem Code von einem Programmierer verwendet wird, der sich der Konsequenzen bewußt ist.

Auf keinen Fall darf »"use strict;"« einfach zu bestehendem Code hinzugefügt werden, da es diesen dann nicht verbessert, sondern seine Bedeutung so verändern könnte, daß ohne »"use strict;"« vollkommen korrekter Code nicht mehr korrekt arbeitet!

Die Übernahme von »"use strict";« durch »eval« ⃗

Ein direkter Aufruf  von »eval« ist ein Aufruf von »eval«, in dem die Funktion ohne Kontext aufgerufen und mit dem Namen »eval« bezeichnet wird. Wenn ein Ausdruck angegeben wird, der die Funktion als Ergebnis liefert, aber nicht »eval« lautet, ist es kein  direkter Aufruf, außer »eval« wurde einfach nur eingeklammert.

Bei einem direkten Aufruf von »eval«, wird der strenge Modus von der Umgebung des Aufrufs übernommen, falls er für diese gilt.

Direkter Aufruf
"use strict"; eval( "03" );
SyntaxError: "0"-prefixed octal literals and octal escape sequences are deprecated; for octal literals use the "0o" prefix instead
Kein direkter Aufruf
"use strict"; this.eval( "03" );
3

»"use strict";« als Auswertungsanweisung ⃗

Bei »"use strict";« handelt es sich zunächst einmal um eine Auswertungsanweisung, die eine Zeichenfolge auswertet. Die Auswertung einer Zeichenfolge sollte keine Wirkung haben. Es gibt aber eine Sonderregel für die Anweisung »"use strict";«, derzufolge das Vorkommen jener Anweisung an bestimmten Stellen die JavaScript -Implementation dazu bewegt, folgende Kommandos im strengen Modus zu interpretieren.

Quellen *

Quellen *
http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

Der direkte Aufruf von »eval« *

Hier wird hergeleitet, warum die beiden folgenden Aufruf von »eval«, in ECMAScript  2016 direkte  Aufrufe sind.

Zwei Aufrufe von »eval«

"use strict"; eval( "03" );

"use strict"; const eval = window.eval; eval( "03" );

0) Beim Aufruf »eval( "05" )« wird der Bezeichner »eval« zuerst nach folgender Regel interpretiert.

12.1.6 Runtime Semantics: Evaluation of IdentifierReference : Identifier
Return ? ResolveBinding(StringValue of Identifier)

Also hier »ResolveBinding( "eval" )«.

1) Danach folgt hier (vereinfacht):

8.3.2 ResolveBinding ( name [ , env ] )
Return ? GetIdentifierReference( global lexical environment, "eval" )

2) Danach folgt hier (vereinfacht):

8.1.2.1 GetIdentifierReference( global lexical environment, name )
Return [ null, "eval" ]

»eval« ist ein Eintrag im globalen Objekt, aber nicht in der globalen lexikalischen Umgebung. Daher wird es in dieser nicht gefunden, und der base-Wert der sich ergebenden Referenz ist »null«. (Hier wird verwendet: 8.1 „The global environment's outer environment reference is null.“, dies wird für die Schritte 4 und 5 in 8.1.2.1 mit einer Rekursion verwendet.)

3) Nun müssen wird (laut 12.3.4.1) folgendes auswerten:

6.2.3 IsPropertyReference( [null, eval] )
true if either the base value is an object or HasPrimitiveBase(V) is true

Da hier der base-Wert gleich »null« ist, ist dies »false«. (Es wäre auch »false«, wenn man »eval« noch in die globale lexikalische Umgebung einbauen würde, da diese kein Objekt ist.)

4) Nun können wir den Funktionsaufruf betrachten.

12.3.4.1 Runtime Semantics: Evaluation of a function call
3. If Type(ref) is Reference and IsPropertyReference(ref) is false and GetReferencedName(ref) is "eval", then
a. If SameValue(func, %eval%) is true, then

Diese Bedingungen bestimmen einen direkten  eval-Aufruf und sind nun tatsächlich alle erfüllt.

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram723579 stefan_ram:723579 use strict in JavaScript Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd723579, slrprddef723579, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/use_strict_javascript