Over strict mode in JavaScript
JavaScript is van oorsprong een 'anarchistische' programmeertaal, waarin bijna alles wat een naam heeft een variabele is die je een waarde kunt geven of mee kunt rekenen. Je kunt zelfs functions deleten of waarden toekennen aan eigenschappen die read-only zijn. Dit wordt ook wel 'sloppy' (= slordig, of slonzig) genoemd. Het is de benadering van normaal JavaScript.
Voor eenvoudige toepassingen is dat prima, maar JavaScript-applicaties worden, net als alle software, steeds ingewikkelder.
Het bouwen van ingewikkelde applicaties met een sloppy programmeertaal vraagt zorgvuldig werken. Één typefout
in een variabele kan al onvoorspelbaar gedrag van de hele applicatie veroorzaken. Dit soort fouten is moeilijk te vinden,
ook gereedschappen als DevTools, die in alle moderne browsers aanwezig zijn.
Zeker voor wat grotere toepassingen zou een meer gestructureerde benadering helpend kunnen zijn.
Om meer gestructureerd te kunnen programmeren in JavaScript is in de loop der tijd een aantal aanpassingen gerealiseerd:
- Invoering van const en let als verbetering van var. Waar var een variabele of constante definieert, is dat met let en const gescheiden.
- Om code-segmenten te scheiden zijn de modules bedacht.
- Om zorgvuldig programmeren af te dwingen kan strict mode worden ingezet in een normaal programma. Binnen modules is dat verplicht.
strict mode wordt ingeschakeld met het directief
"use strict"
. Dit kan gelden voor het hele script-bestand of alleen binnen een code-blok. Het directief moet
wel het eerste statement binnen het bestand of blok zijn.
Oude JavaScript-versies, die strict mode nog niet ondersteunen, zien het directief als een geldige
string zonder toekenning of methode. Ze negeren dat.
In strict mode gedraagt JavaScript zich op essentiële punten anders dan bij normaal JavaScript. De volgende opsomming is ontleend aan w3schools.com en van commentaar voorzien gebaseerd op andere bronnen, zoals Stack Overflow.
- strict mode: Een variable gebruiken zonder die eerst te declareren is niet toegestaan. Een object is ook een variabele,
dat moet dus ook worden gedeclareerd.
- gewoon JavaScript: Niet-gedeclareerde variabelen en objecten worden bij het eerste gebruik aangemaakt met de waarde
undefined.
- strict mode: Het deleten van een variabele of object is niet toegestaan.
gewoon JavaScript: Variabelen en objecten kunnen worden deleted mits die NIET zijn aangemaakt met var of let.
Object properties kunnen alleen worde deleted als dat dat bij de definities is toegestaan.functions kunnen nooit worden deleted.
- strict mode: Dubble parameters in een function zijn niet toegestaan. De code function abc(x,x) {} levert dus
een foutmelding op.
gewoon JavaScript: Dubble parameters in een function zijn toegestaan. De code function abc(x,x) {} is mogelijk]. Maar of het zin heeft?
- strict mode: Octale getallen (grondtal 8) zijn niet toegestaan. Dit is gedaan om het gebruik ervan tegen te gaan.
Het getal 010 kan nl. als 10 worden geïnterpreteerd (grondtal 10), maar ook als 8 (grondtal 8). Dit is op te lossen met
parseInt(010,8).
gewoon JavaScript: Octale getallen zijn toegestaan, maar zijn gevoelig voor fouten en onvoorspelbaar gedrag van het script.
- strict mode: Octale escape sequences zijn niet toegestaan, om dezelfde reden als die waarom octale getallen in het
algemeen niet mogen.
gewoon JavaScript: Octale escape sequences zijn toegestaan, maar zijn gevoelig voor fouten.
- strict mode: Het is niet toegestaan om een waarde toe te kennen aan een read-only of get-only variabele of object-eigenschap.
gewoon JavaScript: Het toekennen van een waarde aan een read-only of get-only variabele of object-eigenschap is mogelijk zonder dat dat een foutmelding geeft, behalve bij een const. Het heeft overigens geen zin, want een dergelijke opdracht wordt niet uitgevoerd.
- strict mode: Het deleten van een als 'undeletable' gemarkeerde object-eigenschap is niet toegestaan.
gewoon JavaScript: Het deleten van een als 'undeletable' gemarkeerde object-eigenschap is niet toegestaan, maar geeft geen foutmelding.
- strict mode: Het statement with is niet toegestaan.
gewoon JavaScript: Het statement with kan gewoon worden gebruikt.
- strict mode: Het woord 'arguments' is de naam van een default JavaScript-object, waar de parameters van een function
in staan. Dit mag niet worden gebruikt als naam voor een variabele.
gewoon JavaScript: Het woord 'arguments' kan gewoon worden gebruikt als naam voor een variabele.
- strict mode: Het woord 'eval' is de naam van een default JavaScript-function waarmee o.a. eenvoudige berekeningen
kunnen worden gemaakt. Dit mag niet worden gebruikt als naam voor een variabele.
gewoon JavaScript: Het woord 'eval' mag niet worden gebruikt als naam voor een variabele.
In het algemeen is eval() een veiligheidsrisico. Met eval() is het mogelijk om (kwaadaardige) code te injecteren in een webdocument en moet daarom alleen worden gebruikt als het echt niet anders kan.
- strict mode: Het maken van variabelen met eval() is niet toegestaan. De code
eval("x = 2")
, ofeval("var x = 2")
ofeval("let x = 2")
mag dus niet.
gewoon JavaScript: Het maken van variabelen met eval() is mogelijk, behalve met let.
In het algemeen geldt dat het niet is toegestaan om met eval() variabelen te maken als de binnen de scope van eval() zelf vallen.
- strict mode: Het keyword this refereert aan het object die de function this aanroept. Als dat niet
is gespecificeerd geeft het undefined terug.
gewoon JavaScript: Het keyword this refereert aan het object die de function this aanroept. Als dat niet is gespecificeerd geeft het een verwijzing terug naar het globale object (= windows).
Keywords die zijn gereserveerd voor gebruik in strict mode in toekomstige JavaScript-versies, mogen niet worden
gebruikt als naam van een variabele. Het gaat hier om:
implements, interface, package, private, protected, public, static en yield.
Deze lijst is niet uitputtend, maar is slechts een indicatie. Diverse bronnen geven tegenstrijdige informatie.
Wat moet je hier mee?
Je kunt je afvragen of je nu helemaal in strict mode moet gaan programmeren of niet. Probeer in elk geval niet om bestaande
code om te zetten van gewoon JavaScript naar strict mode. Dat is, door afwijkende manier waarop strict mode
omgaat met o.a. geldigheid van variabelen, vragen om problemen. Beide systemen door elkaar gebruiken is mogelijk, maar kan
verwarrend zijn. Het debuggen van dergelijke scripts is niet alleen lastig, het is gewoon moeilijk.
De beste aanpak is volgens mij: Blijf programmeren zoals je dat gewend bent. Declareer alle variabelen en objecten vóór
je ze gebruikt en wees nauwkeurig. Als je een beginner bent, doe dan alles met strict mode, maar dan ook echt álles.
Vermijd het gebruik van eval(), meestal kun je daar door anders te coderen wel omheen.