Le mode strict est une partie importante du JavaScript moderne. C'est ce mode qui permet aux développeurs d'utiliser une syntaxe plus limitée que la syntaxe standard.
La sémantique du mode strict est différente du mode traditionnel non strict, qui est parfois appelé «mode bâclé». Dans ce mode, les règles de syntaxe de la langue ne sont pas aussi strictes et lorsque certaines erreurs se produisent, le système n'en informe pas l'utilisateur. Autrement dit, les erreurs peuvent être ignorées et le code dans lequel elles sont produites peut être exécuté davantage. Cela peut conduire à des résultats d'exécution de code inattendus.

Le mode strict introduit quelques changements dans la sémantique de JavaScript. Il empêche le système de fermer les yeux sur les erreurs en lançant des exceptions appropriées. Cela provoque l'arrêt du programme.
Le mode strict, en outre, aide à écrire des programmes dans lesquels il n'y a pas de défauts qui empêchent les moteurs JS d'optimiser le code. De plus, dans ce mode, il est interdit d'utiliser des éléments de syntaxe qui pourraient avoir une signification particulière dans les futures versions du langage.
Caractéristiques de l'utilisation du mode strict
Le mode strict peut être appliqué à des fonctions individuelles ou à un script entier. Il ne peut pas être appliqué uniquement à des instructions individuelles ou à des blocs de code entre accolades. Afin d'utiliser le mode strict au niveau de l'ensemble du script, au tout début du fichier, avant toute autre commande, vous devez mettre l'
"use strict"
ou
'use strict'
construction
'use strict'
.
Si le projet contient des scripts qui n'utilisent pas le mode strict et d'autres qui utilisent ce mode, il peut arriver que ces scripts soient fusionnés.
Cela conduira au fait que le code qui n'est pas destiné à être exécuté en mode strict sera dans un tel état lorsque le système essaiera de l'exécuter en mode strict. L'inverse est également possible - le code écrit pour le mode strict tombera en mode non strict. Par conséquent, il est préférable de ne pas mélanger les scripts «stricts» et «non stricts».
Comme déjà mentionné, le mode strict peut être appliqué aux fonctions individuelles. Pour ce faire
"use strict"
ou
'use strict'
doit être placée en haut du corps de la fonction, avant toute autre commande. Le mode strict de cette approche s'applique à tout ce qui est placé dans le corps de la fonction, y compris les fonctions imbriquées.
Par exemple:
const strictFunction = ()=>{ 'use strict'; const nestedFunction = ()=>{
Dans les modules JavaScript apparus dans la norme ES2015, le mode strict est activé par défaut. Par conséquent, lorsque vous travaillez avec eux, vous n'avez pas besoin de l'inclure explicitement.
Modifications apportées au code JS par mode strict
Le mode strict affecte à la fois la syntaxe du code et la façon dont le code se comporte pendant l'exécution du programme. Les erreurs dans le code sont converties en exceptions. Le fait qu'en mode silencieux plante silencieusement en mode strict provoque un message d'erreur. Ceci est similaire à la façon dont le système répond aux erreurs de syntaxe en mode laxiste. En mode strict, le travail avec les variables est simplifié, l'utilisation de la fonction
eval
et l'objet
arguments
sont strictement réglementés, et le travail avec les constructions qui peuvent être implémentées dans les futures versions du langage est rationalisé.
▍ Convertir les erreurs silencieuses en exceptions
Les erreurs silencieuses sont converties en mode strict en exceptions. En mode laxiste, le système ne répond pas explicitement à de telles erreurs. En mode strict, la présence de telles erreurs conduit à une inopérabilité du code.
Ainsi, grâce à cela, il est difficile de commettre l'erreur de déclarer accidentellement une variable globale, car les variables et les constantes en mode strict ne peuvent pas être déclarées sans utiliser les directives
var
,
let
ou
const
. Par conséquent, la création de variables sans ces directives entraînera une inopérabilité du programme. Par exemple, la tentative d'exécution du code suivant lèvera une exception
ReferenceError
:
'use strict'; badVariable = 1;
Un tel code ne peut pas être exécuté en mode strict, car si le mode strict était désactivé, il créerait une variable globale
badVariable
. Le mode strict empêche le programmeur de créer par inadvertance des variables globales.
Une tentative d'exécution d'un code qui, en mode normal, ne fonctionne tout simplement pas, lève maintenant une exception. Les erreurs sont considérées comme des constructions syntaxiques incorrectes qui ont simplement été ignorées en mode laxiste.
Ainsi, par exemple, en mode strict, vous ne pouvez pas effectuer d'opérations d'attribution de valeur sur des entités en lecture seule telles que des
arguments
,
NaN
ou
eval
.
En mode strict, une exception, par exemple, sera levée dans les cas suivants:
- une tentative d'attribution d'une valeur à une propriété en lecture seule, telle qu'une sorte de propriété globale réinscriptible;
- une tentative d'écrire une valeur dans une propriété qui n'a qu'un getter;
- Une tentative d'écrire quelque chose dans une propriété d'un objet non extensible.
Voici des exemples de constructions de syntaxe menant à des exceptions de mode strictes:
'use strict'; let undefined = 5; let Infinity = 5; let obj = {}; Object.defineProperty(obj, 'foo', { value: 1, writable: false }); obj.foo = 1 let obj2 = { get foo() { return 17; } }; obj2.foo = 2 let fixedObj = {}; Object.preventExtensions(fixedObj); fixed.bar= 1;
Tenter d'exécuter de tels fragments de code en mode strict
TypeError
une exception
TypeError
. Par exemple,
undefined
et
Infinity
sont des entités globales dont les valeurs ne peuvent pas être écrasées et la propriété
foo
de l'objet
obj
ne prend pas en charge la réécriture. La propriété
foo
de
obj2
n'a qu'un getter. L'objet
fixedObj
rendu non extensible à l'aide de la méthode
Object.preventExtensions
.
Une tentative de suppression d'une
TypeError
entraînera également
TypeError
:
'use strict'; delete Array.prototype
Le mode strict interdit d'attribuer des propriétés du même nom à un objet. Par conséquent, une tentative d'exécution du code suivant entraînera une erreur de syntaxe:
'use strict'; let o = { a: 1, a: 2 };
Le mode strict requiert que les noms des paramètres de fonction soient uniques. En mode non strict, si, par exemple, deux paramètres d'une fonction ont le même nom, alors, lors du passage de la fonction d'argument, la valeur du paramètre sera celle qui est tombée dans l'argument déclaré en dernier.
En mode strict, les paramètres des fonctions du même nom sont interdits. Par conséquent, une tentative d'exécution du code suivant entraînera une erreur de syntaxe:
'use strict'; const multiply = (x, x, y) => x*x*y;
En mode strict, vous ne pouvez pas utiliser la notation octale des nombres, précédant le nombre de zéro. Ce n'est pas dans la spécification, mais cette fonctionnalité est prise en charge par les navigateurs.
Cet état de choses confond les développeurs, les obligeant à croire que le 0 précédant le nombre est simplement ignoré, sans grand sens. En mode strict, essayer d'utiliser un nombre au début duquel est 0 entraînera une erreur de syntaxe.
Le mode strict interdit également l'utilisation de constructions qui entravent l'optimisation. L'interpréteur, avant d'effectuer l'optimisation du code, doit savoir que la variable est stockée exactement où, selon l'interprète, elle est stockée. En mode strict, les choses qui interfèrent avec les optimisations sont interdites.
Un exemple d'une telle interdiction concerne la déclaration
with
. Si vous utilisez cette instruction, cela empêche l'interpréteur JS de savoir à quelle variable ou à quelle propriété nous faisons référence, car il est possible qu'une entité du même nom existe à la fois à l'extérieur et à l'intérieur du bloc de l'instruction
with
.
Supposons qu'il existe un code comme celui-ci:
let x = 1; with (obj) { x; }
L'interpréteur ne pourra pas savoir si la variable
x
située à l'intérieur du bloc
with
fait référence à la variable externe
x
ou à la propriété
obj.x
de l'objet
obj
.
Par conséquent, on ne sait pas exactement où la valeur
x
sera située en mémoire. Afin de se débarrasser de telles ambiguïtés, en mode strict, l'utilisation de l'instruction
with
est interdite. Voyons ce qui se passe si vous essayez d'exécuter le code suivant en mode strict:
'use strict'; let x = 1; with (obj) { x; }
Le résultat de cette tentative sera une erreur de syntaxe.
Même en mode strict, il est interdit de déclarer des variables dans le code passé à la méthode
eval
.
Par exemple, en mode normal, une commande de la forme
eval('let x')
entraînera la déclaration de la variable
x
. Cela permet aux programmeurs de masquer les déclarations de variables dans des chaînes, ce qui peut conduire à écraser les définitions des mêmes variables en dehors de
eval
.
Pour éviter cela, en mode strict, il est interdit de déclarer des variables dans le code passé en chaîne à la méthode
eval
.
Le mode strict interdit également la suppression des variables régulières. Par conséquent, la tentative d'exécution du code suivant entraînera une erreur de syntaxe:
'use strict'; let x; delete x;
▍ Interdire les constructions de syntaxe incorrectes
En mode strict, l'utilisation incorrecte de
eval
et des
arguments
interdite. Il s'agit d'une interdiction de toutes sortes de manipulations avec eux. Par exemple, cela revient à leur attribuer de nouvelles valeurs, en utilisant leurs noms comme noms de variable, fonctions, paramètres de fonction.
Voici des exemples d'utilisation abusive de l'
eval
et des
arguments
:
'use strict'; eval = 1; arguments++; arguments--; ++eval; eval--; let obj = { set p(arguments) { } }; let eval; try { } catch (arguments) { } try { } catch (eval) { } function x(eval) { } function arguments() { } let y = function eval() { }; let eval = ()=>{ }; let f = new Function('arguments', "'use strict'; return 1;");
En mode strict, vous ne pouvez pas créer d'alias pour l'objet
arguments
et définir de nouvelles valeurs d'
arguments
via ces alias.
En mode normal, si le premier paramètre de la fonction est
a
, la définition de la valeur de
a
dans le code de fonction entraîne également une modification de la valeur dans les
arguments[0]
. En mode strict, les
arguments
contiendront toujours la liste des arguments avec lesquels la fonction a été appelée.
Supposons que vous ayez le code suivant:
const fn = function(a) { 'use strict'; a = 2; return [a, arguments[0]]; } console.log(fn(1))
La console obtiendra
[2,1]
. En effet, l'écriture d'une valeur de 2 dans
a
n'écrit pas une valeur de 2 dans les
arguments[0]
.
▍Optimisez les performances
En mode strict, la propriété
arguments.callee
n'est pas prise en charge. En mode normal, il retourne le nom de la fonction parent de la fonction dont nous
callee
propriété
callee
de l'objet
arguments
.
La prise en charge de cette propriété interfère avec les optimisations, telles que les fonctions en ligne, car l'utilisation d'
arguments.callee
nécessite la disponibilité d'une référence à une fonction non intégrée lors de l'accès à cette propriété. En mode strict, l'utilisation d'
arguments.callee
déclenche une exception
TypeError
.
En mode strict, le
this
-
this
ne doit pas toujours être un objet. Dans des circonstances normales, si
this
fonction est liée, à l'aide de
call
,
apply
ou
bind
, à quelque chose qui n'est pas un objet, à une valeur de type primitif comme
undefined
,
null
,
number
ou
boolean
, une telle valeur doit être un objet.
Si le contexte de
this
change en quelque chose qui n'est pas un objet, un objet global prend sa place. Par exemple,
window
. Cela signifie que si vous appelez une fonction en définissant son
this
sur une valeur qui n'est pas un objet, au lieu de cette valeur, une référence à l'objet global y tombera.
Prenons un exemple:
'use strict'; function fn() { return this; } console.log(fn() === undefined); console.log(fn.call(2) === 2); console.log(fn.apply(null) === null); console.log(fn.call(undefined) === undefined); console.log(fn.bind(true)() === true);
Toutes les commandes
console.log
afficheront
true
, car en mode strict, la valeur de
this
dans la fonction n'est pas automatiquement remplacée par une référence à l'objet global si
this
définie sur une valeur qui n'est pas un objet.
▍ Modifications liées à la sécurité
En mode strict, vous ne pouvez pas rendre publiques les propriétés de la fonction
caller
et
arguments
. Le fait est que l'
caller
, par exemple, peut donner accès à la fonction qui a appelé la fonction dont nous accédons à la propriété de l'
caller
.
L'objet
arguments
stocke les arguments passés à la fonction lors de son appel. Par exemple, si nous avons une fonction
fn
, cela signifie que via
fn.caller
vous pouvez accéder à la fonction qui a appelé la fonction, et en utilisant
fn.arguments
vous pouvez voir les arguments passés à
fn
lors de son appel.
Ces fonctionnalités présentent un risque potentiel pour la sécurité. Par conséquent, l'accès à ces propriétés est interdit en mode strict.
function secretFunction() { 'use strict'; secretFunction.caller; secretFunction.arguments; } function restrictedRunner() { return secretFunction(); } restrictedRunner();
Dans l'exemple précédent, nous ne pouvons pas, en mode strict, accéder à
secretFunction.caller
et
secretFunction.arguments
. Le fait est que ces propriétés peuvent être utilisées pour obtenir une pile d'appels de fonction. Si vous essayez d'exécuter ce code, une exception
TypeError
sera
TypeError
.
En mode strict, les identifiants pouvant être utilisés dans les futures versions de JavaScript ne peuvent pas être utilisés pour nommer des variables ou des propriétés d'objets. Par exemple, nous parlons des identifiants suivants:
implements
,
interface
,
let
,
package
,
private
,
protected
,
public
,
static
et
yield
.
Dans ES2015 et dans les versions ultérieures de la norme, ces identifiants sont devenus des mots réservés. Et ils ne peuvent pas être utilisés pour nommer des variables ou des propriétés en mode strict.
Résumé
Le mode strict est une norme qui existe depuis de nombreuses années. Il bénéficie d'un support de navigateur extrêmement large. Les problèmes avec le code en mode strict ne peuvent se produire que dans les navigateurs plus anciens, comme Internet Explorer.
Les navigateurs modernes ne devraient pas avoir de difficulté avec le mode JavaScript strict. Par conséquent, nous pouvons dire que ce mode doit être utilisé pour éviter les erreurs «silencieuses» et pour augmenter la sécurité des applications. Les erreurs silencieuses sont converties en exceptions qui gênent l'exécution des programmes et en termes d'amélioration de la sécurité, par exemple, des mécanismes en mode strict qui restreignent l'
eval
et empêchent l'accès à la pile d'appels de fonction peuvent être notés. De plus, l'utilisation du mode strict facilite l'optimisation du code du moteur JS et oblige le programmeur à gérer soigneusement les mots réservés qui pourraient être utilisés dans les futures versions de JavaScript.
Chers lecteurs! Utilisez-vous le mode strict lors de l'écriture de code JS pour vos projets?
