Que fait «utiliser strictement» en JavaScript et quel est le raisonnement derrière cela?

7550

Récemment, j'ai exécuté une partie de mon code JavaScript via JSLint de Crockford , et il a donné l'erreur suivante:

Problème à la ligne 1, caractère 1: instruction "use strict" manquante.

En faisant quelques recherches, j'ai réalisé que certaines personnes ajoutent "use strict";à leur code JavaScript. Une fois que j'ai ajouté la déclaration, l'erreur a cessé d'apparaître. Malheureusement, Google n'a pas révélé une grande partie de l'histoire derrière cette déclaration de chaîne. Certes, cela doit avoir quelque chose à voir avec la façon dont le JavaScript est interprété par le navigateur, mais je n'ai aucune idée de l'effet.

Alors "use strict";, qu'est-ce que cela implique, qu'est-ce que cela implique et est-il toujours pertinent?

Est-ce que l'un des navigateurs actuels répond à la "use strict";chaîne ou est-ce pour une utilisation future?

Mark Rogers
la source
5
Les réponses ici sont anciennes mais elles sont fausses. Le raisonnement principal pour le mode strict n'était pas d'empêcher les erreurs de programmation - c'était de faire une portée lexicale de JavaScript afin qu'il puisse être analysé statiquement:]
Benjamin Gruenbaum
@BenjaminGruenbaum L'utilisation "use strict";seule ne rend pas JS à portée lexicale. La déclaration des variables avec letet constdoit également être utilisée.
Koorosh Pasokhi
Vous mélangez la portée de bloc et la portée lexicale.
Benjamin Gruenbaum

Réponses:

4939

Cet article sur Javascript Strict Mode pourrait vous intéresser: John Resig - ECMAScript 5 Strict Mode, JSON, etc.

Pour citer quelques parties intéressantes:

Le mode strict est une nouvelle fonctionnalité d'ECMAScript 5 qui vous permet de placer un programme, ou une fonction, dans un contexte de fonctionnement "strict". Ce contexte strict empêche certaines actions d'être prises et lève plus d'exceptions.

Et:

Le mode strict aide de plusieurs façons:

  • Il attrape quelques bêtises de codage courantes, levant des exceptions.
  • Il empêche ou génère des erreurs lorsque des actions relativement "dangereuses" sont prises (telles que l'accès à l'objet global).
  • Il désactive les fonctionnalités déroutantes ou mal pensées.

Notez également que vous pouvez appliquer le "mode strict" à l'ensemble du fichier ... Ou vous pouvez l'utiliser uniquement pour une fonction spécifique (toujours en citant l'article de John Resig) :

// Non-strict code...

(function(){
  "use strict";

  // Define your library strictly...
})();

// Non-strict code... 

Ce qui pourrait être utile si vous devez mélanger l'ancien et le nouveau code ;-)

Donc, je suppose que c'est un peu comme le que "use strict"vous pouvez utiliser en Perl (d'où le nom?) : Il vous aide à faire moins d'erreurs, en détectant plus de choses qui pourraient conduire à des ruptures.

Le mode strict est désormais pris en charge par tous les principaux navigateurs .

Dans les modules ECMAScript natifs (avec importet exportinstructions) et les classes ES6 , le mode strict est toujours activé et ne peut pas être désactivé.

Pascal MARTIN
la source
100
Changer la valeur par défaut après tant d'années? Trop tard pour cela: cela briserait tant de sites / scripts / applications existants ... La seule chose possible est d'aider à améliorer les choses, pour l'avenir.
Pascal MARTIN
14
J'ai essayé un petit extrait de code qui ne serait pas valide lors de l'utilisation "use strict"dans Firefox 3.6, Safari 5, Chrome 7 et Opera 10.6 (tous Mac). Aucune erreur, donc je suppose que `` utiliser strictement '' n'est pas encore pris en charge dans aucun navigateur. N'a pas testé dans IE9 cependant;)
Husky
11
Mise à jour rapide: Firefox 4 a un support complet pour le mode strict, et pour autant que je sache, aucun autre navigateur ne le fait. Safari et Chrome ont un support "partiel", mais je ne sais pas vraiment ce que cela signifie.
Sasha Chedygov
29
Chrome 11 semble passer tous ces tests, tout comme IE10 ie.microsoft.com/testdrive/HTML5/TryStrict/Default.html#
gman
12
@Julius - Cela n'aurait pas pu être implémenté à l'aide d'un mot clé réservé, car alors le code essayant de déclencher le mode strict se briserait dans les anciens navigateurs. L'ajout d'un littéral de chaîne "aléatoire" ne casse rien.
nnnnnn
1245

C'est une nouvelle fonctionnalité d'ECMAScript 5. John Resig en a rédigé un joli résumé .

C'est juste une chaîne que vous mettez dans vos fichiers JavaScript (en haut de votre fichier ou à l'intérieur d'une fonction) qui ressemble à ceci:

"use strict";

Le mettre dans votre code maintenant ne devrait pas poser de problème avec les navigateurs actuels car c'est juste une chaîne. Cela peut entraîner des problèmes avec votre code à l'avenir si votre code viole le pragma. Par exemple, si vous en avez actuellement foo = "bar"sans définir d' fooabord, votre code commencera à échouer ... ce qui est une bonne chose à mon avis.

seth
la source
329
Échouez vite et échouez fort.
Niels Bom
31
Si vous écrivez Javascript en ligne dans des fichiers HTML, démarrez chaque nouveau bloc avec <script>"use strict";. Le drapeau ne s'applique qu'au bloc dans lequel il est inclus.
nobar
7
C'est drôle, cela a pour conséquence que les chaînes doivent avoir des guillemets simples. Alors écrivez à la 'use strict';place
nilsi
1
qu'adviendrait-il alors du concept de levage de javascript?
Sunil Sharma
1
@SunilSharma Si vous essayez de hisser, mais qu'il échoue car la variable n'est pas définie, il l'ajoutera pour le moment à l'objet global. Avec "use strict";, cela échouera à la place. Cela a plus de sens, car s'il l'ajoute à l'objet global, cela signifie qu'il peut ne pas fonctionner la prochaine fois que vous exécutez la fonction / faites quelque chose d'autre qui réinitialise le bloc, car il se trouvera dans le bloc le plus élevé (global).
wizzwizz4
646

L'instruction "use strict";demande au navigateur d'utiliser le mode strict, qui est un ensemble de fonctionnalités réduites et plus sûres de JavaScript.

Liste des fonctionnalités (non exhaustive)

  1. Interdit les variables globales. (Capture les vardéclarations manquantes et les fautes de frappe dans les noms de variables)

  2. Les affectations silencieuses qui échouent génèrent une erreur en mode strict (affectation NaN = 5;)

  3. Les tentatives de suppression de propriétés non supprimables lanceront ( delete Object.prototype)

  4. Exige que tous les noms de propriété d'un littéral d'objet soient uniques ( var x = {x1: "1", x1: "2"})

  5. Les noms des paramètres de fonction doivent être uniques ( function sum (x, x) {...})

  6. Interdit la syntaxe octale ( var x = 023;certains développeurs supposent à tort qu'un zéro précédent ne fait rien pour changer le nombre.)

  7. Interdit le withmot clé

  8. eval en mode strict n'introduit pas de nouvelles variables

  9. Interdit la suppression de noms en clair ( delete x;)

  10. Interdit la liaison ou l'attribution des noms evalet argumentssous quelque forme que ce soit

  11. Le mode strict n'aliase pas les propriétés de l' argumentsobjet avec les paramètres formels. (c'est-à-dire dans function sum (a,b) { return arguments[0] + b;}Cela fonctionne parce que arguments[0]est lié à aet ainsi de suite.)

  12. arguments.callee n'est pas pris en charge

[Ref: Mode strict , Mozilla Developer Network ]

gprasant
la source
40
Nit: les variables globales sont autorisées, doivent juste être explicites (par exemple window.foo = bar).
gcampbell
1
Exige que tous les noms de propriété dans un littéral d'objet soient uniques (var x = {x1: "1", x1: "2"}) est-ce valide
Arun Killu
4
Votre exemple en 11 manque une modification de a (sinon cela n'a aucun sens). C'est à dire. fonction somme (a, b) {a = 0; renvoie des arguments [0] + b; } alert (sum (1, 2)) renverra 3 avec le mode strict et 2 sans le mode strict, en raison de l'aliasing.
David Gausmann
413

Si les gens s'inquiètent de son utilisation, use strictil peut être utile de consulter cet article:

Prise en charge du mode strict par ECMAScript 5 dans les navigateurs. Qu'est-ce que ça veut dire?
NovoGeek.com - le blog de Krishna

Il parle de la prise en charge du navigateur, mais plus important encore, de la manière de le gérer en toute sécurité:

function isStrictMode(){
    return !this;
} 
/*
   returns false, since 'this' refers to global object and 
   '!this' becomes false
*/

function isStrictMode(){   
    "use strict";
    return !this;
} 
/* 
   returns true, since in strict mode the keyword 'this'
   does not refer to global object, unlike traditional JS. 
   So here, 'this' is 'undefined' and '!this' becomes true.
*/
Jamie Hutber
la source
116
Je ne suis pas d'accord. Je pense que cela montre pourquoi c'est très utile. En substance, cela signifie que cela retourne sa fonction et non lewindow
Jamie Hutber
36
quand voulez-vous jamais la fenêtre avec thislaquelle vous ne pouvez pas cibler window?
Jamie Hutber
14
Il se réfère à lui-même. thisappartient à sa propre fonction et non à la fenêtre globale
Jamie Hutber
26
Dans le second, thisc'est en fait undefined.
Broxzier
14
Le fait est que votre programme JS commencera à échouer en raison de l'accès à une propriété d'un non défini, au lieu de faire silencieusement la mauvaise chose sur l'objet global. Rend la recherche de bogues subtils beaucoup plus facile.
Stephen Chung
208

Un mot d'avertissement, vous tous les programmeurs en charge: appliquer "use strict"au code existant peut être dangereux! Cette chose n'est pas un autocollant joyeux et joyeux que vous pouvez gifler sur le code pour le rendre «meilleur». Avec le "use strict"pragma, le navigateur jettera soudain des exceptions dans des endroits aléatoires qu'il n'a jamais lancés auparavant simplement parce qu'à cet endroit, vous faites quelque chose que le JavaScript par défaut / lâche permet avec bonheur mais abhorre JavaScript strict! Vous pouvez avoir des violations de rigueur se cachant dans les appels rarement utilisés dans votre code qui ne lèveront une exception que lorsqu'ils seront finalement exécutés - par exemple, dans l'environnement de production que vos clients payants utilisent!

Si vous allez franchir le pas, c'est une bonne idée de l'appliquer "use strict"aux côtés de tests unitaires complets et d'une tâche de construction JSHint strictement configurée qui vous donnera une certaine assurance qu'il n'y a pas de coin sombre de votre module qui explosera horriblement juste parce que vous 'ai activé le mode strict. Ou, hé, voici une autre option: n'ajoutez rien "use strict"à votre code hérité, c'est probablement plus sûr de cette façon, honnêtement. DÉFINITIVEMENT NE PAS ajouter "use strict"à des modules que vous ne possédez pas ou ne maintenez pas, comme des modules tiers.

Je pense que même s'il s'agit d'un animal en cage mortel, cela "use strict"peut être une bonne chose, mais vous devez le faire correctement. Le meilleur moment pour devenir strict est lorsque votre projet est entièrement nouveau et que vous partez de zéro. Configurez JSHint/JSLintavec tous les avertissements et options montés aussi serrés que votre équipe peut l'estimer, obtenez un bon système de construction / test / affirmation du jour truqué Grunt+Karma+Chai, et seulement ALORS commencez à marquer tous vos nouveaux modules comme "use strict". Soyez prêt à remédier à de nombreuses erreurs et avertissements. Assurez-vous que tout le monde comprend la gravité en configurant la génération sur FAIL si elle JSHint/JSLintproduit des violations.

Mon projet n'était pas un projet vierge lorsque j'ai adopté "use strict". En conséquence, mon IDE est plein de marques rouges parce que je n'ai pas"use strict" sur la moitié de mes modules, et JSHint s'en plaint. C'est un rappel pour moi de ce que je devrais refactoriser à l'avenir. Mon objectif est d'être libre de toute marque rouge en raison de toutes mes "use strict"déclarations manquantes , mais c'est dans des années.

DWoldrich
la source
24
POURQUOI les développeurs de ce fil sont-ils si cavaliers à propos de "l'utilisation stricte" ?? Il jette des exceptions dans JavaScript autrement fonctionnant , pour l'amour de Dieu! Saupoudrez-le sur le code comme du sucre sur des Corn Flakes, hein? NON! MAUVAIS! "use strict" doit être utilisé avec prudence, de préférence uniquement dans le code que vous contrôlez qui a des tests unitaires qui passent contre tous les principaux navigateurs et qui exercent tous les chemins de code. Vous avez des tests? D'accord, "utiliser strictement" vous convient, assommez-vous.
DWoldrich
57
Oui. De toute évidence, "utiliser strictement" peut briser un javascript apparemment valide qui ne l'a pas été auparavant. Mais le code n'ayant pas cassé avant n'est pas égal au code étant correct et faisant ce qu'il est censé faire. Le fait de référencer généralement des variables non déclarées signale une faute de frappe, etc. L'utilisation stricte vous permet de détecter ce type d'erreurs et, espérons-le, avant d'envoyer le code de production.
Jostein Kjønigsen
5
... ou appliquez simplement "use strict" dans le cadre d'un dernier passage sur votre code, corrigez tous les problèmes évidents, haussez les épaules, dites "assez bien", puis retirez-le pour la production :)
Wolfie Inu
13
Personnellement, je n'ajoute jamais / très rarement "use strict";au code existant. Cela étant dit, je l'utilise presque toujours lorsque j'écris du nouveau code à partir de zéro
Martin
3
Si vous utilisez déjà JSLint, vous avez probablement corrigé la plupart des endroits où "utiliser strict" casserait les choses.
Jonathan Cast
179

L'utilisation 'use strict';n'améliore pas soudainement votre code.

le mode strict JavaScript est une fonctionnalité d' ECMAScript 5 . Vous pouvez activer le mode strict en le déclarant en haut de votre script / fonction.

'use strict';

Lorsqu'un moteur JavaScript voit cette directive , il commence à interpréter le code dans un mode spécial. Dans ce mode, des erreurs sont émises lorsque certaines pratiques de codage qui pourraient finir par être des bogues potentiels sont détectées (ce qui est le raisonnement derrière le mode strict).

Considérez cet exemple:

var a = 365;
var b = 030;

Dans son obsession d'aligner les littéraux numériques, le développeur a par inadvertance initialisé une variable b avec un littéral octal. Le mode non strict interprétera cela comme un littéral numérique avec valeur 24(en base 10). Cependant, le mode strict générera une erreur.

Pour une liste non exhaustive des spécialités en mode strict, voir cette réponse .


Où devrais-je utiliser 'use strict'; ?

  • Dans ma nouvelle application JavaScript: Absolument! Le mode strict peut être utilisé comme un lanceur d'alerte lorsque vous faites quelque chose de stupide avec votre code.

  • Dans mon code JavaScript existant : Probablement pas! Si votre code JavaScript existant contient des instructions interdites en mode strict, l'application se cassera simplement. Si vous voulez un mode strict, vous devez être prêt à déboguer et à corriger votre code existant. C'est pourquoi l' utilisation 'use strict';n'améliore pas soudainement votre code .


Comment utiliser le mode strict?

  1. Insérez une 'use strict';déclaration au-dessus de votre script:

    // File: myscript.js
    
    'use strict';
    var a = 2;
    ....

    Notez que tout dans le fichier myscript.jssera interprété en mode strict.

  2. Ou, insérez une 'use strict';déclaration au-dessus de votre corps de fonction:

    function doSomething() {
        'use strict';
        ...
    }

    Tout dans la portée lexicale de la fonction doSomethingsera interprété en mode strict. Le mot portée lexicale est important ici. Par exemple, si votre code strict appelle une fonction d'une bibliothèque qui n'est pas stricte , seul votre code est exécuté en mode strict, et non la fonction appelée. Voir cette réponse pour une meilleure explication.


Quelles sont les choses interdites en mode strict?

J'ai trouvé un bel article décrivant plusieurs choses interdites en mode strict (notez que ce n'est pas une liste exclusive):

Portée

Historiquement, JavaScript a été confus quant à la portée des fonctions. Parfois, ils semblent avoir une portée statique, mais certaines fonctionnalités les font se comporter comme s'ils avaient une portée dynamique. C'est déroutant, ce qui rend les programmes difficiles à lire et à comprendre. Un malentendu provoque des bugs. C'est également un problème de performances. La portée statique permettrait à la liaison de variables de se produire au moment de la compilation, mais l'exigence de portée dynamique signifie que la liaison doit être reportée à l'exécution, ce qui entraîne une pénalité de performance significative.

Le mode strict nécessite que toutes les liaisons de variables soient effectuées de manière statique. Cela signifie que les fonctionnalités qui nécessitaient auparavant une liaison dynamique doivent être supprimées ou modifiées. Plus précisément, l'instruction with est supprimée et la capacité de la fonction eval à altérer l'environnement de son appelant est sévèrement limitée.

Un des avantages du code strict est que des outils comme YUI Compressor peuvent faire un meilleur travail lors de son traitement.

Variables globales implicites

JavaScript a impliqué des variables globales. Si vous ne déclarez pas explicitement une variable, une variable globale est implicitement déclarée pour vous. Cela facilite la programmation pour les débutants car ils peuvent négliger certaines de leurs tâches ménagères de base. Mais cela rend la gestion de programmes plus importants beaucoup plus difficile et dégrade considérablement la fiabilité. Ainsi, en mode strict, les variables globales implicites ne sont plus créées. Vous devez déclarer explicitement toutes vos variables.

Fuite mondiale

Il existe un certain nombre de situations qui pourraient entraîner this la liaison à l'objet global. Par exemple, si vous oubliez de fournir le newpréfixe lors de l'appel d'une fonction constructeur, le constructeur thissera lié de manière inattendue à l'objet global, donc au lieu d'initialiser un nouvel objet, il modifiera silencieusement les variables globales. Dans ces situations, le mode strict se liera thisà la place àundefined , ce qui obligera le constructeur à lever une exception à la place, permettant à l'erreur d'être détectée beaucoup plus tôt.

Échec bruyant

JavaScript a toujours eu des propriétés en lecture seule, mais vous ne pouviez pas les créer vous-même avant l'ES5 Object.createProperty fonction expose cette capacité. Si vous tentiez d'affecter une valeur à une propriété en lecture seule, elle échouerait silencieusement. L'affectation ne changerait pas la valeur de la propriété, mais votre programme se déroulerait comme s'il l'avait fait. Il s'agit d'un risque d'intégrité qui peut entraîner un état incohérent des programmes. En mode strict, la tentative de modification d'une propriété en lecture seule lèvera une exception.

Octal

La représentation octale (ou base 8) des nombres était extrêmement utile lors de la programmation au niveau machine sur des machines dont la taille des mots était un multiple de 3. Vous aviez besoin d'octal lorsque vous travailliez avec l'unité centrale CDC 6600, qui avait une taille de mot de 60 bits. Si vous pouviez lire l'octal, vous pourriez regarder un mot à 20 chiffres. Deux chiffres représentaient le code op et un chiffre identifiait l'un des 8 registres. Pendant la transition lente des codes machine vers les langages de haut niveau, il a été jugé utile de fournir des formes octales dans les langages de programmation.

En C, une représentation extrêmement malheureuse de l'octalité a été choisie: Zéro en tête. Donc en C, 0100signifie 64, pas 100, et 08c'est une erreur, pas 8. Encore plus malheureusement, cet anachronisme a été copié dans presque tous les langages modernes, y compris JavaScript, où il n'est utilisé que pour créer des erreurs. Cela n'a pas d'autre but. Donc en mode strict, les formes octales ne sont plus autorisées.

Etc

Le pseudo tableau d'arguments devient un peu plus semblable à un tableau dans ES5. En mode strict, il perd ses propriétés calleeet caller. Cela permet de passer votre argumentscode non fiable sans renoncer à beaucoup de contexte confidentiel. De plus, la argumentspropriété des fonctions est supprimée.

En mode strict, les clés en double dans un littéral de fonction produiront une erreur de syntaxe. Une fonction ne peut pas avoir deux paramètres avec le même nom. Une fonction ne peut pas avoir de variable du même nom que l'un de ses paramètres. Une fonction ne peut pas avoir deleteses propres variables. Une tentative vers deleteune propriété non configurable lève désormais une exception. Les valeurs primitives ne sont pas implicitement encapsulées.


Mots réservés pour les futures versions de JavaScript

ECMAScript 5 ajoute une liste de mots réservés. Si vous les utilisez comme variables ou arguments, le mode strict générera une erreur. Les mots réservés sont:

implements, interface, let, package, private, protected, public, staticEtyield


Lectures complémentaires

sampathsris
la source
2
c'est une très belle explication. Cependant, j'ai un doute sur le fait que je peux utiliser le mode "strict" en conjonction avec d'autres bibliothèques de scripts java, comme Angular js?
UVM
3
@UVM: La directive en mode strict affecte uniquement la portée lexicale. c'est-à-dire uniquement le fichier / la fonction qu'il est déclaré. Si vous avez un autre fichier / fonction qui n'a pas la 'use strict'directive, ils seront exécutés en mode non strict, même lorsqu'ils sont appelés à partir d'une fonction s'exécutant en mode strict. Voir cette réponse pour une explication.
sampathsris
Ce n'est pas tout à fait correct. 'use strict' change la façon dont le code est exécuté.
CyberEd
3
Au deuxième regard, vous avez raison. Je pensais que vous vouliez dire que cela ne levait que des exceptions, mais ne changeait pas la façon dont le code fonctionnait (comme changer this). Maintenant, je vois que vous parliez d'appeler d'autres fonctions.
CyberEd
3
Il y a des cas où l'octal est utile. La syntaxe C pour elle est horrible, mais j'aurais aimé voir les langages ajouter une nouvelle syntaxe octale qui pourrait alors permettre la dépréciation de la forme zéro en tête. Bien sûr, pour Javascript, avoir supporté la forme zéro en tête était tout simplement idiot.
supercat
138

Je recommande fortement à chaque développeur de commencer à utiliser le mode strict maintenant. Il y a suffisamment de navigateurs qui le prennent en charge pour que le mode strict nous aide légitimement à éviter des erreurs que nous ne savions même pas dans votre code.

Apparemment, au stade initial, il y aura des erreurs que nous n'avons jamais rencontrées auparavant. Pour obtenir tous les avantages, nous devons effectuer des tests appropriés après le passage en mode strict pour nous assurer que nous avons tout pris. Certainement, nous ne nous contentons pas de jeter use strictnotre code et de supposer qu'il n'y a pas d'erreurs. Donc, le désabonnement est qu'il est temps de commencer à utiliser cette fonctionnalité de langage incroyablement utile pour écrire un meilleur code.

Par exemple,

var person = {
    name : 'xyz',
    position : 'abc',
    fullname : function () {  "use strict"; return this.name; }
};

JSLint est un débogueur écrit par Douglas Crockford. Collez simplement votre script et il recherchera rapidement tout problème ou erreur notable dans votre code.

Pank
la source
6
@JamieHutber: Veuillez visiter ce lien caniuse.com/use-strict AND kangax.github.io/es5-compat-table . Il donnera une idée exacte de tous les navigateurs.
Pank
95

Je voudrais proposer une réponse un peu plus fondée complétant les autres réponses. J'espérais éditer la réponse la plus populaire, mais j'ai échoué. J'ai essayé de le rendre aussi complet et complet que possible.

Vous pouvez vous référer à la documentation MDN pour plus d'informations.

"use strict" une directive introduite dans ECMAScript 5.

Les directives sont similaires aux déclarations, mais différentes.

  • use strictne contient pas de mots clés: la directive est une instruction d'expression simple, qui consiste en un littéral de chaîne spécial (entre guillemets simples ou doubles). Les moteurs JavaScript, qui n'implémentent pas ECMAScript 5, voient simplement une instruction d'expression sans effets secondaires. Il est prévu que les futures versions des normes ECMAScript introduisent useun véritable mot clé; les citations deviendraient ainsi obsolètes.
  • use strictne peut être utilisé qu'au début d'un script ou d'une fonction, c'est-à-dire qu'il doit précéder toute autre instruction (réelle). Il n'est pas nécessaire que ce soit la première instruction dans un script de fonction: elle peut être précédée d'autres expressions d'instruction qui se composent de littéraux de chaîne (et les implémentations JavaScript peuvent les traiter comme des directives spécifiques à l'implémentation). Les instructions de littéraux de chaîne, qui suivent une première instruction réelle (dans un script ou une fonction) sont des instructions d'expression simples. Les interprètes ne doivent pas les interpréter comme des directives et ils n'ont aucun effet.

La use strictdirective indique que le code suivant (dans un script ou une fonction) est un code strict. Le code au plus haut niveau d'un script (code qui n'est pas dans une fonction) est considéré comme un code strict lorsque le script contient une use strictdirective. Le contenu d'une fonction est considéré comme un code strict lorsque la fonction elle-même est définie dans un code strict ou lorsque la fonction contient une use strictdirective. Le code transmis à une eval()méthode est considéré comme un code strict lorsqu'il a eval()été appelé à partir d'un code strict ou contient la use strictdirective elle-même.

Le mode strict d'ECMAScript 5 est un sous-ensemble restreint du langage JavaScript, qui élimine les déficits pertinents du langage et propose une vérification des erreurs plus stricte et une sécurité plus élevée. Voici une liste des différences entre le mode strict et le mode normal (dont les trois premiers sont particulièrement importants):

  • Vous ne pouvez pas utiliser la withdéclaration-en mode strict.
  • En mode strict, toutes les variables doivent être déclarées: si vous attribuez une valeur à un identifiant qui n'a pas été déclaré comme variable, fonction, paramètre de fonction, paramètre catch-clause ou propriété du global Object, vous obtiendrez un ReferenceError. En mode normal, l'identifiant est implicitement déclaré comme une variable globale (comme une propriété du global Object)
  • En mode strict, le mot-clé thisa la valeur undefineddans les fonctions qui ont été invoquées en tant que fonctions (pas en tant que méthodes). (En mode normal, thispointe toujours vers le global Object). Cette différence peut être utilisée pour tester si une implémentation prend en charge le mode strict:
var hasStrictMode = (function() { "use strict"; return this===undefined }());
  • De même, lorsqu'une fonction est invoquée avec call()ou applyen mode strict, alors thisest exactement la valeur du premier argument de l' invocation call()or apply(). (En mode normal nullet undefinedsont remplacés par le global Objectet les valeurs, qui ne sont pas des objets, sont converties en objets.)

  • En mode strict, vous obtiendrez un TypeError , lorsque vous essayez d'affecter à des propriétés en lecture seule ou de définir de nouvelles propriétés pour un objet non extensible. (En mode normal, les deux échouent simplement sans message d'erreur.)

  • En mode strict, lorsque eval()vous passez du code à , vous ne pouvez pas déclarer ou définir des variables ou des fonctions dans la portée de l'appelant (comme vous pouvez le faire en mode normal). Au lieu de cela, une nouvelle étendue est créée pour eval()et les variables et fonctions sont dans cette étendue. Cette portée est détruite une fois l' eval()exécution terminée.
  • En mode strict, l'argument-objet d'une fonction contient une copie statique des valeurs, qui sont passées à cette fonction. En mode normal, l'argument-objet a un comportement quelque peu "magique": les éléments du tableau et les paramètres de fonction nommés font référence à la même valeur.
  • En mode strict, vous obtiendrez un SyntaxErrorlorsque l' deleteopérateur est suivi d'un identifiant non qualifié (variable, fonction ou paramètre de fonction). En mode normal, l' deleteexpression ne ferait rien et est évaluée àfalse .
  • En mode strict, vous obtiendrez un TypeErrorlorsque vous essayez de supprimer une propriété non configurable. (En mode normal, la tentative échoue simplement et l' deleteexpression est évaluée à false).
  • En mode strict, il est considéré comme une erreur syntaxique lorsque vous essayez de définir plusieurs propriétés avec le même nom pour un littéral d'objet. (En mode normal, il n'y a pas d'erreur.)
  • En mode strict, il est considéré comme une erreur syntaxique lorsqu'une déclaration de fonction a plusieurs paramètres avec le même nom. (En mode normal, il n'y a pas d'erreur.)
  • En mode strict, les littéraux octaux ne sont pas autorisés (ce sont des littéraux qui commencent par 0x . (En mode normal, certaines implémentations autorisent les littéraux octaux.)
  • En mode strict les identifiants evalet argumentssont traités comme des mots-clés. Vous ne pouvez pas modifier leur valeur, ne pouvez pas leur attribuer une valeur et vous ne pouvez pas les utiliser comme noms pour des variables, des fonctions, des paramètres de fonction ou des identificateurs d'un bloc catch.
  • En mode strict, il y a plus de restrictions sur les possibilités d'examiner la pile d'appels. arguments.calleret arguments.calleeprovoquer un TypeErrordans une fonction en mode strict. De plus, certaines propriétés d'appel et d'argument des fonctions en mode strict provoquent un TypeErrorlorsque vous essayez de les lire.
Ely
la source
4
"En mode strict, les littéraux octaux ne sont pas autorisés (ce sont des littéraux qui commencent par 0x ...)" Les littéraux octaux commencent par un interligne 0.
Alex Gittemeier
83

Mes deux centimes:

L'un des objectifs du mode strict est de permettre un débogage plus rapide des problèmes. Il aide les développeurs en lançant une exception lorsque certaines mauvaises choses se produisent qui peuvent provoquer un comportement silencieux et étrange de votre page Web. Le moment où nous utilisonsuse strict , le code générera des erreurs qui aideront le développeur à le corriger à l'avance.

Peu de choses importantes que j'ai apprises après utilisation use strict:

Empêche la déclaration de variable globale:

var tree1Data = { name: 'Banana Tree',age: 100,leafCount: 100000};

function Tree(typeOfTree) {
    var age;
    var leafCount;

    age = typeOfTree.age;
    leafCount = typeOfTree.leafCount;
    nameoftree = typeOfTree.name;
};

var tree1 = new Tree(tree1Data);
console.log(window);

Maintenant, ce code crée nameoftreeune portée globale accessible à l'aide de window.nameoftree. Lorsque nous implémentons use strictle code, cela génère une erreur.

Uncaught ReferenceError: nameoftree n'est pas défini

Sample

Élimine la withdéclaration:

withles instructions ne peuvent pas être minifiées à l'aide d'outils comme uglify-js . Ils sont également obsolètes et supprimés des futures versions de JavaScript.

Sample

Empêche les doublons:

Lorsque nous avons une propriété en double, elle lève une exception

SyntaxError non capturée: la propriété de données en double dans le littéral objet n'est pas autorisée en mode strict

"use strict";
var tree1Data = {
    name: 'Banana Tree',
    age: 100,
    leafCount: 100000,
    name:'Banana Tree'
};

Il y en a peu mais j'ai besoin d'acquérir plus de connaissances à ce sujet.

Shubh
la source
Avec ECMAScript 2015, les noms de propriété en double sont à nouveau autorisés! Voir la documentation MDN .
philmcole
62

Si vous utilisez un navigateur sorti au cours de la dernière année, il prend probablement en charge le mode JavaScript Strict. Seuls les navigateurs plus anciens avant ECMAScript 5 sont devenus la norme actuelle ne le prennent pas en charge.

Les guillemets autour de la commande garantissent que le code fonctionnera également dans les anciens navigateurs (bien que les choses qui génèrent une erreur de syntaxe en mode strict provoquent généralement un dysfonctionnement du script d'une manière difficile à détecter dans ces anciens navigateurs).

Stephen
la source
12
Alors qu'est-ce que ça fait?
Anish Gupta
7
... cela décrit en partie la compatibilité, mais pas ce qu'elle fait réellement.
courtsimas
58

Lors de l'ajout "use strict";, les cas suivants lèveront une SyntaxError avant l'exécution du script:

  • Préparer le terrain pour la future version de ECMAScript , en utilisant l' un des mots - clés nouvellement réservés (pour en prevision ECMAScript 6 ): implements, interface, let, package, private, protected, public, staticet yield.

  • Déclarer la fonction en blocs

    if(a<b){ function f(){} }
  • Syntaxe octale

    var n = 023;
  • this pointez sur l'objet global.

     function f() {
          "use strict";
          this.a = 1;
     };
     f(); 
  • Déclarer deux fois le même nom pour un nom de propriété dans un objet littéral

     {a: 1, b: 3, a: 7} 

    Ce n'est plus le cas dans ECMAScript 6 ( bug 1041128 ).

  • Déclaration de deux arguments de fonction avec la même fonction de nom

    f(a, b, b){}
  • Définition d'une valeur sur une variable non déclarée

    function f(x){
       "use strict";
       var a = 12;
       b = a + x*35; // error!
    }
    f();
  • Utilisation deletesur un nom de variabledelete myVariable;

  • Utilisation de evalou argumentscomme nom d'argument de variable ou de fonction

    "use strict";
    arguments++;
    var obj = { set p(arguments) { } };
    try { } catch (arguments) { }
    function arguments() { } 

Sources:

zangw
la source
Avec ECMAScript 2015, les noms de propriété en double sont à nouveau autorisés! Voir la documentation MDN .
philmcole
53

Le mode strict apporte plusieurs modifications à la sémantique JavaScript normale:

  • élimine certaines erreurs silencieuses JavaScript en les modifiant pour générer des erreurs.

  • corrige les erreurs qui empêchent les moteurs JavaScript d'effectuer des optimisations.

  • interdit certaines syntaxes susceptibles d'être définies dans les futures versions d'ECMAScript.

pour plus d'informations vistit Strict Mode- Javascript

Renganathan MG
la source
52

"Utiliser strictement"; est une assurance que le programmeur n'utilisera pas les propriétés lâches ou mauvaises de JavaScript. C'est un guide, tout comme une règle vous aidera à faire des lignes droites. "Utiliser Strict" vous aidera à "coder directement".

Ceux qui préfèrent ne pas utiliser de règles pour faire leurs lignes directement se retrouvent généralement dans ces pages demandant à d'autres de déboguer leur code.

Crois moi. La surcharge est négligeable par rapport à un code mal conçu. Doug Crockford, qui est un développeur JavaScript senior depuis plusieurs années, a un poste très intéressant ici . Personnellement, j'aime revenir tout le temps sur son site pour m'assurer de ne pas oublier ma bonne pratique.

La pratique JavaScript moderne devrait toujours évoquer le "Use Strict"; pragma. La seule raison pour laquelle le groupe ECMA a rendu le mode "Strict" facultatif est de permettre aux codeurs moins expérimentés d'accéder à JavaScript et de leur donner ensuite le temps de s'adapter aux nouvelles pratiques de codage plus sûres.

user2436758
la source
66
La raison pour laquelle le mode strict est facultatif n'a rien à voir avec ce que vous avez déclaré. La vraie raison est de ne pas casser le code existant qui peut ne pas être conforme .
Dexygen
17
En effet, les codeurs les moins expérimentés devraient être les premiers à permettre "l'utilisation stricte";
Antti Haapala
46

Inclure use strictau début de tous vos fichiers JavaScript sensibles à partir de ce point est un petit moyen d'être un meilleur programmeur JavaScript et d'éviter que les variables aléatoires ne deviennent globales et que les choses changent silencieusement.

Espace réservé
la source
42

Citant de w3schools :

La directive "use strict"

La directive "use strict" est nouvelle dans JavaScript 1.8.5 (ECMAScript version 5).

Ce n'est pas une déclaration, mais une expression littérale, ignorée par les versions antérieures de JavaScript.

Le but de "use strict" est d'indiquer que le code doit être exécuté en "mode strict".

En mode strict, vous ne pouvez pas, par exemple, utiliser des variables non déclarées.

Pourquoi le mode strict?

Le mode strict facilite l'écriture de JavaScript «sécurisé».

Le mode strict transforme les "mauvaises syntaxes" précédemment acceptées en erreurs réelles.

Par exemple, en JavaScript normal, une faute de frappe sur un nom de variable crée une nouvelle variable globale. En mode strict, cela générera une erreur, rendant impossible la création accidentelle d'une variable globale.

En JavaScript normal, un développeur ne recevra aucun retour d'erreur affectant des valeurs à des propriétés non inscriptibles.

En mode strict, toute affectation à une propriété non accessible en écriture, une propriété de lecture seule, une propriété non existante, une variable non existante ou un objet non existant, générera une erreur.

Veuillez vous référer à http://www.w3schools.com/js/js_strict.asp pour en savoir plus

Heich-B
la source
37

"use strict"fait exécuter du code JavaScript en mode strict , ce qui signifie essentiellement que tout doit être défini avant utilisation. La principale raison de l'utilisation du mode strict est d'éviter les utilisations globales accidentelles de méthodes non définies.

Également en mode strict, les choses fonctionnent plus vite, certains avertissements ou avertissements silencieux génèrent des erreurs fatales, il est préférable de toujours l'utiliser pour créer un code plus net.

"use strict"est largement nécessaire pour être utilisé dans ECMA5, dans ECMA6, il fait partie de JavaScript par défaut , il n'a donc pas besoin d'être ajouté si vous utilisez ES6.

Regardez ces déclarations et exemples de MDN:

La directive "use strict"
La "use strict" est nouvelle dans JavaScript 1.8.5 (ECMAScript version 5). Ce n'est pas une déclaration, mais une expression littérale, ignorée par les versions antérieures de JavaScript. Le but de "use strict" est d'indiquer que le code doit être exécuté en "mode strict". En mode strict, vous ne pouvez pas, par exemple, utiliser des variables non déclarées.

Exemples d'utilisation de "use strict":
Mode strict pour les fonctions: De même, pour invoquer le mode strict pour une fonction, mettez l'expression exacte "use strict"; (ou 'use strict';) dans le corps de la fonction avant toute autre déclaration.

1) mode strict dans les fonctions

 function strict() {
     // Function-level strict mode syntax
     '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."; }

 console.log(strict(), notStrict());

2) Mode strict de script entier

'use strict';
var v = "Hi! I'm a strict mode script!";
console.log(v);

3) Affectation à un global non accessible en écriture

'use strict';

// Assignment to a non-writable global
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError

// Assignment to a non-writable property
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // throws a TypeError

// Assignment to a getter-only property
var obj2 = { get x() { return 17; } };
obj2.x = 5; // throws a TypeError

// Assignment to a new property on a non-extensible object.
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // throws a TypeError

Vous pouvez en savoir plus sur MDN .

Alireza
la source
31

Il y a une bonne discussion par certaines personnes qui faisaient partie du comité ECMAScript: Modifications de JavaScript, partie 1: ECMAScript 5 " sur la façon dont l'utilisation incrémentielle de la"use strict" commutateur permet aux implémenteurs JavaScript de nettoyer de nombreuses fonctionnalités dangereuses de JavaScript sans casser soudainement tous les sites Web dans le monde.

Bien sûr, il parle également de ce que beaucoup de ces erreurs sont (étaient) et comment ECMAScript 5 les corrige.

FutureNerd
la source
27

Petits exemples à comparer:

Mode non strict:

for (i of [1,2,3]) console.log(i)
    
// output:
// 1
// 2
// 3

Mode strict:

'use strict';
for (i of [1,2,3]) console.log(i)

// output:
// Uncaught ReferenceError: i is not defined

Mode non strict:

String.prototype.test = function () {
  console.log(typeof this === 'string');
};

'a'.test();

// output
// false

String.prototype.test = function () {
  'use strict';
  
  console.log(typeof this === 'string');
};

'a'.test();

// output
// true

Bronzer
la source
2
Notez que le code ci-dessus ajoutera la variable i à la portée globale (généralement ce n'est pas une bonne pratique et le mode strict permet d'éviter cela).
michael
1
Quelqu'un peut-il expliquer le deuxième exemple? Je ne comprends pas. Ne devrait pas this === 'a'dans les deux exemples?
MaximeW
19

Notez que cela a use strictété introduit dans EcmaScript 5 et a été conservé depuis lors.

Voici les conditions pour déclencher le mode strict dans ES6 et ES7 :

  • Le code global est un code de mode strict s'il commence par un prologue de directive qui contient une directive d'utilisation stricte (voir 14.1.1).
  • Le code du module est toujours un code de mode strict.
  • Toutes les parties d'une déclaration de classe ou d'une expression de classe sont un code de mode strict.
  • Le code Eval est un code en mode strict s'il commence par un prologue de directive qui contient une directive Use Strict ou si l'appel à eval est un eval direct (voir 12.3.4.1) contenu dans un code en mode strict.
  • Le code de fonction est un code de mode strict si le FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, MethodDefinition ou ArrowFunction associé est contenu dans le code de mode strict ou si le code qui produit la valeur de l'emplacement interne [[ECMAScriptCode]] de la fonction commence par un Prologue de directive qui contient une directive d'utilisation stricte.
  • Le code de fonction fourni comme arguments aux constructeurs de fonction et de générateur intégrés est un code de mode strict si le dernier argument est une chaîne qui, lorsqu'elle est traitée, est un FunctionBody qui commence par un prologue de directive contenant une directive d'utilisation stricte.
Oriol
la source
14

Les principales raisons pour lesquelles les développeurs devraient utiliser "use strict"sont:

  1. Empêche la déclaration accidentelle de variables globales.Using "use strict()"s'assurera que les variables sont déclarées avec varavant utilisation. Par exemple:

    function useStrictDemo(){
     'use strict';
     //works fine
     var a = 'No Problem';
    
     //does not work fine and throws error
     k = "problem"
    
     //even this will throw error
     someObject = {'problem': 'lot of problem'};
    }
  2. NB: La "use strict"directive n'est reconnue qu'au début d'un script ou d'une fonction.
  3. La chaîne "arguments"ne peut pas être utilisée comme variable:

    "use strict";
    var arguments = 3.14;    // This will cause an error
  4. Limitera l'utilisation des mots clés comme variables. Essayer de les utiliser générera des erreurs.

En bref, votre code sera moins sujet aux erreurs et vous fera à son tour écrire un bon code.

Pour en savoir plus, vous pouvez vous référer ici .

Pritam Banerjee
la source
12

"utiliser strict"; est l'effort de l'ECMA pour rendre JavaScript un peu plus robuste. Il apporte à JS une tentative de le rendre au moins un peu "strict" (d'autres langages implémentent des règles strictes depuis les années 90). En fait, cela "oblige" les développeurs JavaScript à suivre une sorte de bonnes pratiques de codage. Pourtant, JavaScript est très fragile. Il n'y a rien de tel que les variables typées, les méthodes typées, etc. Je recommande fortement aux développeurs JavaScript d'apprendre un langage plus robuste tel que Java ou ActionScript3, et d'implémenter les mêmes bonnes pratiques dans votre code JavaScript, cela fonctionnera mieux et sera plus facile à déboguer.

PippoApps.com
la source
12

Le mode «strict» JavaScript a été introduit dans ECMAScript 5.

(function() {
  "use strict";
  your code...
})();

L'écriture "use strict";tout en haut de votre fichier JS active la vérification stricte de la syntaxe. Il effectue les tâches suivantes pour nous:

  1. affiche une erreur si vous essayez d'affecter à une variable non déclarée

  2. vous empêche d'écraser les bibliothèques système JS clés

  3. interdit certaines fonctionnalités linguistiques dangereuses ou sujettes aux erreurs

use strictfonctionne également à l'intérieur des fonctions individuelles. Il est toujours préférable d'inclure use strictdans votre code.

Problème de compatibilité du navigateur: les directives "use" sont censées être rétrocompatibles. Les navigateurs qui ne les prennent pas en charge verront simplement un littéral de chaîne qui n'est plus référencé. Alors, ils passeront dessus et continueront.

Rabin Pantha
la source
12

use strictest un moyen de rendre votre code plus sûr, car vous ne pouvez pas utiliser des fonctionnalités dangereuses qui ne fonctionnent pas comme prévu. Et, comme cela a été écrit auparavant, cela rend le code plus strict.

Просто программист
la source
11

Utiliser Strict est utilisé pour afficher les erreurs courantes et répétées afin qu'il soit traité différemment, et change la façon dont le script java s'exécute, ces modifications sont:

  • Empêche les globaux accidentels

  • Pas de doublons

  • Élimine avec

  • Élimine cette contrainte

  • Eval plus sûr ()

  • Erreurs pour les immuables

vous pouvez également lire cet article pour les détails

Wesam
la source
11

Normalement, JavaScript ne suit pas de règles strictes, augmentant ainsi les risques d'erreurs. Après utilisation "use strict", le code JavaScript doit suivre un ensemble de règles strictes comme dans d'autres langages de programmation tels que l'utilisation de terminateurs, la déclaration avant l'initialisation, etc.

Si "use strict"est utilisé, le code doit être écrit en suivant un ensemble strict de règles, diminuant ainsi les risques d'erreurs et d'ambiguïtés.

Bikash Chapagain
la source
7

"utiliser strict"; Définit que le code JavaScript doit être exécuté en "mode strict".

  • La directive "use strict" était nouvelle dans ECMAScript version 5.
  • Ce n'est pas une déclaration, mais une expression littérale, ignorée par les versions antérieures de JavaScript.
  • Le but de "use strict" est d'indiquer que le code doit être exécuté en "mode strict".
  • En mode strict, vous ne pouvez pas, par exemple, utiliser des variables non déclarées.

Tous les navigateurs modernes prennent en charge "utiliser strictement" à l'exception d' Internet Explorer 9 et des versions antérieures .

Désavantage

Si un développeur utilisait une bibliothèque qui était en mode strict, mais qu'il était habitué à travailler en mode normal, il pourrait appeler des actions sur la bibliothèque qui ne fonctionneraient pas comme prévu.

Pire, puisque le développeur est en mode normal, il n'a pas l'avantage de générer des erreurs supplémentaires, de sorte que l'erreur peut échouer en silence.

En outre, comme indiqué ci-dessus, le mode strict vous empêche de faire certaines choses.

Les gens pensent généralement que vous ne devriez pas utiliser ces choses en premier lieu, mais certains développeurs n'aiment pas la contrainte et souhaitent utiliser toutes les fonctionnalités du langage.

Ashish
la source
4

Le mode strict peut empêcher les fuites de mémoire.

Veuillez vérifier la fonction ci-dessous écrite en mode non strict:

function getname(){
    name = "Stack Overflow"; // Not using var keyword
    return name;
}
getname();
console.log(name); // Stack Overflow

Dans cette fonction, nous utilisons une variable appelée nameà l'intérieur de la fonction. En interne, le compilateur vérifiera d'abord s'il existe une variable déclarée avec ce nom particulier dans cette portée de fonction particulière. Étant donné que le compilateur a compris qu'il n'y a pas une telle variable, il vérifiera la portée externe. Dans notre cas, c'est la portée mondiale. Encore une fois, le compilateur a compris qu'il n'y avait pas non plus de variable déclarée dans l'espace global avec ce nom, donc il crée une telle variable pour nous dans l'espace global. Conceptuellement, cette variable sera créée dans la portée globale et sera disponible dans toute l'application.

Un autre scénario est que, disons, la variable est déclarée dans une fonction enfant. Dans ce cas, le compilateur vérifie la validité de cette variable dans la portée externe, c'est-à-dire la fonction parent. Ce n'est qu'alors qu'il vérifiera l'espace global et créera une variable pour nous là-bas. Cela signifie que des vérifications supplémentaires doivent être effectuées. Cela affectera les performances de l'application.


Écrivons maintenant la même fonction en mode strict.

"use strict"
function getname(){
    name = "Stack Overflow"; // Not using var keyword
    return name;
}
getname();
console.log(name); 

Nous obtiendrons l'erreur suivante.

Uncaught ReferenceError: name is not defined
at getname (<anonymous>:3:15)
at <anonymous>:6:5

Ici, le compilateur renvoie l'erreur de référence. En mode strict, le compilateur ne nous permet pas d'utiliser la variable sans la déclarer. Ainsi, les fuites de mémoire peuvent être évitées. De plus, nous pouvons écrire du code plus optimisé.

Jerin K Alexander
la source