Question Que fait "use strict" en JavaScript, et quel est le raisonnement derrière?


Récemment, j'ai couru une partie de mon code JavaScript à travers Crockford JSLintet il a donné l'erreur suivante:

Problème à la ligne 1 caractère 1: Manquant "use strict" statement.

En faisant des recherches, j'ai réalisé que certaines personnes ajoutaient "use strict"; dans 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é beaucoup de l'histoire derrière cette déclaration de chaîne. Certes, il 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 ce que l'effet serait.

Donc qu'est-ce "use strict"; tout à propos, qu'est-ce que cela implique, et est-ce toujours pertinent?

Est-ce que l'un des navigateurs actuels répond aux "use strict"; chaîne ou est-ce pour un usage futur?


6702
2017-08-26 16:10


origine


Réponses:


Cet article sur Javascript Strict Mode pourrait vous intéresser: John Resig - ECMAScript 5 Mode strict, JSON, et plus

Pour citer des 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 opérationnel «strict». Ce contexte strict empêche certaines actions d'être prises et jette plus d'exceptions.

Et:

Le mode strict aide de deux façons:

  • Il attrape quelques bêtis de codage communs, jetant des exceptions.
  • Il empêche ou déclenche des erreurs lorsque des actions relativement «dangereuses» sont prises (comme l'accès à l'objet global).
  • Il désactive les fonctionnalités qui sont confuses ou mal conçues.

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

// Non-strict code...

(function(){
  "use strict";

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

// Non-strict code... 

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

Donc, je suppose que c'est un peu comme "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.

Actuellement, c'est pris en charge par tous les principaux navigateurs  (barre IE 9 et ci-dessous).


4392
2017-08-26 16:15



C'est une nouvelle fonctionnalité d'ECMAScript 5. John Resig a écrit un bon résumé de cela.

C'est juste une chaîne que vous mettez dans vos fichiers JavaScript (soit 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 causer de problèmes avec les navigateurs actuels car c'est juste une chaîne. Cela peut causer des problèmes avec votre code dans le futur si votre code viole le pragma. Par exemple, si vous avez actuellement foo = "bar" sans définir foo D'abord, votre code va commencer à échouer ... ce qui est une bonne chose à mon avis.


1101
2017-08-26 16:14



La déclaration "use strict"; demande au navigateur d'utiliser le mode Strict, qui est un ensemble de fonctionnalités JavaScript réduit et plus sûr.

Liste des fonctionnalités (non exhaustive)

  1. Interdit les variables globales. (Captures manquantes var déclarations et fautes de frappe dans les noms de variables)

  2. Les assignations défaillantes silencieuses provoqueront une erreur en mode strict NaN = 5;)

  3. Tentatives de suppression des propriétés indélébilesdelete Object.prototype)

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

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

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

  7. Interdit le with mot-clé

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

  9. Interdit de supprimer des noms simples (delete x;)

  10. Interdit la liaison ou l'attribution des noms eval et arguments de n'importe quelle forme

  11. Le mode strict ne possède pas les propriétés de l'alias arguments objet 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é à a etc. )

  12. arguments.callee n'est pas supporté

[Ref: Mode strict, Réseau de développeurs Mozilla]


518
2017-11-24 21:22



Si les gens s'inquiètent d'utiliser use strict il pourrait être intéressant de vérifier cet article:

ECMAScript 5 'Strict mode' support 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, comment 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.
*/

368
2017-07-15 23:25



Un mot d'avertissement, tous les programmeurs vous chargez dur: application "use strict" au code existant peut être dangereux! Cette chose n'est pas un autocollant de bonne humeur, de joyeux visage que vous pouvez coller sur le code pour le rendre «meilleur». Avec le "use strict" pragma, le navigateur va soudainement LANCER des exceptions dans des endroits aléatoires qu'il n'a jamais jetés auparavant juste parce qu'à cet endroit vous faites quelque chose que JavaScript par défaut laisse libre heureusement mais abhorres JavaScript strictes! Vous pouvez avoir des violations de rigueur se cachant dans les appels rarement utilisés dans votre code qui ne lèveront une exception qu'une fois qu'ils seront finalement exécutés - disons, dans l'environnement de production que vos clients payants utilisent!

Si vous allez franchir le pas, c'est une bonne idée d'appliquer "use strict" avec des tests unitaires complets et une tâche de construction JSHint strictement configurée qui vous donnera l'assurance qu'il n'y a pas de coin sombre de votre module qui explosera horriblement juste parce que vous avez activé le mode strict. Ou, hé, voici une autre option: il suffit de ne pas ajouter "use strict" à l'un de vos anciens codes, c'est probablement plus sûr, honnêtement. DEFINITIVEMENT NE PAS ajouter "use strict" à tous les modules que vous ne possédez pas ou ne maintenez pas, comme les modules tiers.

Je pense que même si c'est un animal en cage mortel, "use strict" peut être bon, mais vous devez le faire correctement. Le meilleur moment pour aller strict est quand votre projet est nouveau et que vous partez de zéro. Configurer JSHint/JSLint avec tous les avertissements et toutes les options qui sont serrés aussi fort que votre équipe peut supporter, obtenez une bonne construction / test / assertion du système gréé comme Grunt+Karma+Chai, et seulement ensuite commencer à marquer tous vos nouveaux modules comme "use strict". Soyez prêt à guérir beaucoup d'erreurs et d'avertissements. Assurez-vous que tout le monde comprend la gravité en configurant la construction à FAIL si JSHint/JSLintproduit des violations.

Mon projet n'était pas un projet greenfield quand 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 se plaint à ce sujet. C'est un rappel pour moi de ce que je devrais faire dans le futur. Mon objectif est d'être libre de toute marque rouge en raison de tous mes manquants "use strict" déclarations, mais c'est des années loin maintenant.


182
2018-03-03 07:37



En utilisant 'use strict'; ne rend pas votre code meilleur tout à coup.

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

'use strict';

Quand un moteur JavaScript voit cela directif, il va commencer à interpréter le code dans un mode spécial. Dans ce mode, les erreurs sont levées lorsque certaines pratiques de codage qui pourraient être des bugs 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 leur obsession d'aligner les littéraux numériques, le développeur a initialisé par inadvertance 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 va lancer 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 mon Nouveau Application JavaScript: Absolument! Le mode strict peut être utilisé comme lanceur d'alerte lorsque vous faites quelque chose de stupide avec votre code.

  • Dans mon existant Code JavaScript: Probablement pas! Si votre code JavaScript existant contient des instructions interdites en mode strict, l'application va simplement se casser. Si vous voulez un mode strict, vous devez être prêt à déboguer et corriger votre code existant. C'est pourquoi en utilisant 'use strict'; ne rend pas votre code meilleur tout à coup.


Comment utiliser le mode strict?

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

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

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

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

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

    Tout dans le portée lexicale de la fonction doSomething sera interprété en mode strict. Le mot portée lexicale est important ici. Voir cette réponse pour une meilleure explication.


Quelles choses sont interdites en mode strict?

j'ai trouvé un bel article décrire plusieurs choses qui sont interdites en mode strict (notez qu'il ne s'agit pas d'une liste exclusive):

Portée

Historiquement, JavaScript a été confus sur la façon dont les fonctions   sont délimités. Parfois, ils semblent avoir une portée statique, mais certains   les caractéristiques les font se comporter comme ils sont dynamiquement scoped. C'est   confusion, rendant les programmes difficiles à lire et à comprendre.   Malentendu provoque des bugs. C'est aussi un problème de performance.   La portée statique permettrait une liaison variable lors de la compilation   temps, mais l'exigence de portée dynamique signifie que la liaison doit être   différé à l'exécution, qui vient avec une performance significative   peine.

Le mode strict exige que toute la liaison de variable soit faite statiquement.   Cela signifie que les fonctionnalités qui nécessitaient auparavant une liaison dynamique   doit être éliminé ou modifié. Plus précisément, l'instruction with est   éliminé, et la capacité de la fonction eval à altérer le   l'environnement de son appelant est sévèrement restreint.

Un des avantages du code strict est que des outils comme Compresseur YUI   peut faire un meilleur travail lors du traitement.

Variables globales implicites

JavaScript a implicite des variables globales. Si   vous ne déclarez pas explicitement une variable, une variable globale est   implicitement déclaré pour vous. Cela facilite la programmation pour   débutants parce qu'ils peuvent négliger une partie de leur entretien ménager de base   corvées. Mais cela rend la gestion des grands programmes beaucoup plus   difficile et dégrade considérablement la fiabilité. Donc, en stricte   mode, les variables globales implicites ne sont plus créées. Vous devriez   déclarez explicitement toutes vos variables.

Fuite globale

Il y a un certain nombre de situations qui pourraient causer this   être lié à l'objet global. Par exemple, si vous oubliez de   fournir le new préfixe lors de l'appel d'une fonction de constructeur, le   constructeur this sera lié de manière inattendue à l'objet global, de sorte   au lieu d'initialiser un nouvel objet, il sera plutôt silencieux   falsification de variables globales. Dans ces situations, le mode strict sera   plutôt lier this à undefined, ce qui amènera le constructeur à   lancer une exception à la place, ce qui permet de détecter beaucoup plus l'erreur   plus tôt.

Échec bruyant

JavaScript a toujours eu des propriétés en lecture seule, mais vous   ne pouvait pas les créer vous-même jusqu'à ES5 Object.createProperty   fonction exposée cette capacité. Si vous avez tenté d'attribuer une valeur   à une propriété en lecture seule, il échouerait silencieusement. L'affectation serait   pas changer la valeur de la propriété, mais votre programme procéderait comme   si c'était le cas. Ceci est un danger d'intégrité qui peut causer des programmes à   entrer dans un état incohérent. En mode strict, tenter de changer un   La propriété en lecture seule lève 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 le mot   les tailles étaient un multiple de 3. Vous aviez besoin d'octal lorsque vous travailliez avec le CDC   6600 mainframe, qui avait une taille de mot de 60 bits. Si vous pouviez lire   octal, vous pourriez regarder un mot comme 20 chiffres. Deux chiffres représentés   le code op, et un chiffre identifié parmi 8 registres. Pendant le   transition lente des codes machine aux langages de haut niveau, il était   pensé pour être utile pour fournir des formes octales dans les langages de programmation.

En C, une représentation extrêmement malheureuse de l'octal   selected: Premier zéro. Donc en C, 0100 signifie 64, pas 100, et 08 est un   erreur, pas 8. Plus malheureusement, cet anachronisme a été   copié dans presque toutes les langues modernes, y compris JavaScript, où   il est seulement utilisé pour créer des erreurs. Il n'a pas d'autre but. Donc dans   mode strict, les formes octales ne sont plus autorisées.

Etc

Les arguments pseudo-array deviennent un peu plus   tableau semblable à ES5. En mode strict, il perd son callee et caller   Propriétés. Cela permet de passer votre arguments à non approuvé   code sans abandonner beaucoup de contexte confidentiel. Également    arguments la propriété des fonctions est éliminée.

En mode strict, les clés dupliquées dans un littéral de fonction produiront un   erreur de syntaxe. Une fonction ne peut pas avoir deux paramètres avec le même nom.   Une fonction ne peut pas avoir une variable avec le même nom que l'une de ses   paramètres. Une fonction ne peut pas delete ses propres variables. Une tentative de    delete une propriété non configurable renvoie maintenant une exception. Primitif   les valeurs 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 en tant que variables ou arguments, le mode strict lancera une erreur. Les mots réservés sont:

implements, interface, let, package, private, protected, public, static, et yield


Lecture supplémentaire


131
2018-01-29 11:35



Je recommande fortement à tous les développeurs de commencer à utiliser le mode strict maintenant. Il y a assez de navigateurs qui supportent ce mode strict qui va légitimement nous sauver des erreurs que nous ne savions même pas dans votre code.

Apparemment, à l'étape initiale, il y aura des erreurs que nous n'avons jamais rencontrées auparavant. Pour obtenir tous les avantages, nous devons faire des tests appropriés après le passage en mode strict pour nous assurer que nous avons tout attrapé. Certainement, nous ne jetons pas seulement use strict dans notre code et supposons qu'il n'y a pas d'erreurs. Donc le baratte 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-le simplement dans votre script et il analysera rapidement les éventuels problèmes et erreurs détectés dans votre code.


122
2017-07-05 19:38



Je voudrais offrir une réponse un peu plus complète 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 à 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 strict ne contient pas de mots clés: La directive est une expression simple, qui consiste en une chaîne littérale spéciale (entre guillemets simples ou doubles). Les moteurs JavaScript, qui n'implémentent pas ECMAScript 5, voient simplement une expression sans effets secondaires. Il est prévu que les futures versions des normes ECMAScript use comme un mot clé réel; les citations deviendraient ainsi obsolètes.
  • use strict peut être utilisé uniquement au début d'un script ou d'une fonction, c'est-à-dire qu'il doit précéder chaque autre instruction (réelle). Il ne doit pas être la première instruction dans un script de fonction: il peut être précédé par d'autres expressions d'instruction constituées de littéraux de chaîne (et les implémentations de JavaScript peuvent les traiter comme des directives spécifiques d'implémentation). Les instructions littérales 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.

le 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 du code strict lorsque le script contient un use strict directif. 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 un use strict directif. Code qui est passé à un eval() méthode est considérée comme un code strict lorsque eval() a été appelé à partir d'un code strict ou contient le use strict directive elle-même.

Le mode strict d'ECMAScript 5 est un sous-ensemble restreint du langage JavaScript, qui élimine les déficits pertinents de la langue et présente des contrôles d'erreurs plus stricts et une sécurité plus élevée. Voici la 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 le with-statement en mode strict.
  • En mode strict, toutes les variables doivent être déclarées: si vous affectez une valeur à un identificateur qui n'a pas été déclaré comme variable, fonction, paramètre de fonction, paramètre catch-clause ou propriété du global Object, alors vous aurez un ReferenceError. En mode normal, l'identificateur est implicitement déclaré en tant que variable globale (en tant que propriété de Object)
  • En mode strict, le mot-clé this a la valeur undefined dans les fonctions qui ont été appelées en tant que fonctions (pas en tant que méthodes). (En mode normal this pointe toujours vers le mondial Object). Cette différence peut être utilisée pour tester si une implémentation supporte le mode strict:
var hasStrictMode = (function() { "use strict"; return this===undefined }());
  • Aussi, lorsqu'une fonction est appelée avec call() ou apply en mode strict, alors this est exactement la valeur du premier argument de la call()ou apply() invocation. (En mode normal null et undefined sont remplacés par le mondial Object et les valeurs, qui ne sont pas des objets, sont transtypées en objets.)

  • En mode strict, vous obtiendrez un TypeError, lorsque vous essayez d'affecter à des propriétés readonly ou pour 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, lors du passage du code à eval(), 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 portée est créée pour eval() et les variables et les fonctions sont dans cette portée. Cette portée est détruite après eval() termine l'exécution.
  • 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-object a un comportement quelque peu "magique": Les éléments du tableau et les paramètres de la fonction nommée font référence à la même valeur.
  • En mode strict, vous obtiendrez un SyntaxError quand le delete L'opérateur est suivi d'un identifiant non qualifié (variable, fonction ou paramètre de fonction). En mode normal, le delete l'expression ne ferait rien et est évaluée à false.
  • En mode strict, vous obtiendrez un TypeError lorsque vous essayez de supprimer une propriété non configurable. (En mode normal, la tentative échoue simplement et le deletel'expression 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 eval et arguments sont traités comme des mots-clés. Vous ne pouvez pas changer leur valeur, vous 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 identifiants d'un bloc catch.
  • En mode strict, il y a plus de restrictions sur les possibilités d'examiner la pile d'appels. arguments.caller et arguments.callee provoquer une TypeError dans une fonction en mode strict. De plus, certaines propriétés de l'appelant et des arguments des fonctions en mode strict provoquent TypeError quand vous essayez de les lire.

81
2018-05-15 06:58