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



Answers

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

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 premier, votre code commencera à échouer ... ce qui est une bonne chose à mon avis.

Question

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

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

En faisant quelques 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.

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

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




The main reasons why developers should use "use strict" are:

  1. Prevents accidental declaration of global variables.Using "use strict()" will make sure that variables are declared with var before use. 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: The "use strict" directive is only recognized at the beginning of a script or a function.
  3. The string "arguments" cannot be used as a variable:

    "use strict";
    var arguments = 3.14;    // This will cause an error
    
  4. Will restrict uses of keywords as variables. Trying to use them will throw errors.

In short will make your code less error prone and in turn will make you write good code.

To read more about it you can refer http://www.w3schools.com/js/js_strict.asp .




"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. "Use Strict" vous aidera à faire un "codage direct".

Ceux qui préfèrent ne pas utiliser les règles pour faire leurs lignes droites finissent généralement dans ces pages en demandant aux autres de déboguer leur code.

Crois moi. Les frais généraux sont négligeables par rapport à un code mal conçu. Doug Crockford, qui est développeur senior de JavaScript depuis plusieurs années, a un article très intéressant ici . Personnellement, j'aime revenir sur son site tout le temps 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" optionnel est de permettre aux codeurs moins expérimentés d'accéder au JavaScript et de leur donner ensuite le temps de s'adapter aux nouvelles pratiques de codage plus sûres.




Just wanted to add some more points.

The Reason to Use Strict Mode--->

  • Strict mode makes it easier to write "secure" JavaScript.

  • Strict mode changes previously accepted "bad syntax" into real
    les erreurs.

  • As an example, in normal JavaScript, mistyping a variable name
    creates a new global variable.

  • In strict mode, this will throw an error, making it impossible to accidentally create a global variable.

  • In strict mode, any assignment to a non-writable property, a
    getter-only property, a non-existing property, a non-existing
    variable, or a non-existing object, will throw an error.

The things that will throw errors in Strict Mode Using a variable, without declaring it, is not allowed:

"use strict";
 x = 3.14;                // This will cause an error

Objects are variables too.

Using an object, without declaring it, is not allowed:

  "use strict";
  x = {p1:10, p2:20};      // This will cause an error

Deleting a variable (or object) is not allowed.

  "use strict";
   var x = 3.14;
   delete x;                // This will cause an error

For security reasons, eval() is not allowed to create variables in the scope from which it was called:

"use strict";
 eval ("var x = 2");
 alert (x);               // This will cause an error

In function calls like f(), the this value was the global object. In strict mode, it is now undefined.

"use strict" is only recognized at the beginning of a script.




Je voudrais offrir une réponse un peu plus complémentaire aux 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 de 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 simple expression, qui consiste en une chaîne littérale spéciale (en 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 versions futures des normes ECMAScript introduisent l' use comme un mot clé réel; les citations deviendraient ainsi obsolètes.
  • use strict ne peut être utilisé qu'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.

La directive use strict indique que le code suivant (dans un script ou une fonction) est du 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 une directive use strict . Le contenu d'une fonction est considéré comme du code strict lorsque la fonction elle-même est définie dans un code strict ou lorsque la fonction contient une directive use strict . Le code qui est passé à une méthode eval() est considéré comme du code strict lorsque eval() été appelé à partir d'un code strict ou contient la directive use strict 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 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 fonction, paramètre catch-clause ou propriété de l' Object global, vous obtiendrez une ReferenceError . En mode normal, l'identificateur est implicitement déclaré en tant que variable globale (en tant que propriété de l' Object global)
  • 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 l' Object global). 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 invoquée avec call() ou apply en mode strict, alors c'est exactement la valeur du premier argument de l' call() ou apply() . (En mode normal, null et undefined sont remplacés par l' Object global et les valeurs, qui ne sont pas des objets, sont transtypées en objets.)

  • En mode strict, vous obtiendrez une TypeError lorsque vous essayez d'assigner des propriétés readonly 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 vous passez 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 fonctions sont dans cette portée. Cette portée est détruite après l'exécution d' eval() .
  • 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 une SyntaxError lorsque l'opérateur de delete est suivi d'un identificateur non qualifié (un paramètre de variable, de fonction ou de fonction). En mode normal, l'expression delete ne fait rien et est évaluée à false .
  • En mode strict, vous obtiendrez une TypeError lorsque vous essayez de supprimer une propriété non configurable. (En mode normal, la tentative échoue simplement et l'expression de delete 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 provoquent un TypeError dans une fonction en mode strict. En outre, certaines propriétés d'appelant et d'arguments des fonctions en mode strict provoquent une TypeError lorsque vous essayez de les lire.



Normally java script does not follow strict rules hence increasing chances of errors. After using "use strict" , the java script code should follow strict set of rules as like in other programming languages such as use of terminators, declaration before initialization etc.

If "use strict" is used then the code should be written by following a strict set of rules hence decreasing the chances of errors and ambiguities.




Note that use strict was introduced in EcmaScript 5 and was kept since then.

Below are the conditions to trigger strict mode in ES6 and ES7 :

  • Global code is strict mode code if it begins with a Directive Prologue that contains a Use Strict Directive (see 14.1.1).
  • Module code is always strict mode code.
  • All parts of a ClassDeclaration or a ClassExpression are strict mode code.
  • Eval code is strict mode code if it begins with a Directive Prologue that contains a Use Strict Directive or if the call to eval is a direct eval (see 12.3.4.1) that is contained in strict mode code.
  • Function code is strict mode code if the associated FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, MethodDefinition, or ArrowFunction is contained in strict mode code or if the code that produces the value of the function's [[ECMAScriptCode]] internal slot begins with a Directive Prologue that contains a Use Strict Directive.
  • Function code that is supplied as the arguments to the built-in Function and Generator constructors is strict mode code if the last argument is a String that when processed is a FunctionBody that begins with a Directive Prologue that contains a Use Strict Directive.



Si les gens s'inquiètent d'utiliser l' use strict il vaut peut-être la peine de consulter 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.
*/



"use strict"; is the ECMA effort to make JavaScript a little bit more robust. It brings in JS an attempt to make it at least a little "strict" (other languages implement strict rules since the 90s). It actually "forces" JavaScript developers to follow some sort of coding best practices. Still, JavaScript is very fragile. There is no such thing as typed variables, typed methods, etc. I strongly recommend JavaScript developers to learn a more robust language such as Java or ActionScript3, and implement the same best practices in your JavaScript code, it will work better and be easier to debug.




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

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, 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 par inadvertance initialisé la variable b avec un littéral octal. Le mode non strict interprétera ceci comme un littéral numérique avec la 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ù dois-je utiliser 'use strict'; ?

  • Dans ma nouvelle 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 code JavaScript existant : 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 utiliser '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 la 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 bon article décrivant plusieurs choses qui sont interdites en mode strict (notez que ce n'est pas une liste exclusive):

Portée

Historiquement, JavaScript a été confus sur la façon dont les fonctions sont étendues. Parfois, ils semblent avoir une portée statique, mais certaines fonctionnalités les font se comporter comme s'ils étaient dynamiquement étendus. C'est déroutant, rendant les programmes difficiles à lire et à comprendre. Malentendu provoque des bugs. C'est aussi un problème de performance. La portée statique permet à la liaison de variable d'avoir lieu au moment de la compilation, mais l'exigence de portée dynamique signifie que la liaison doit être différée à l'exécution, ce qui entraîne une pénalité de performance significative.

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 doivent être éliminées ou modifiées. Plus précisément, l'instruction with est éliminée, et la capacité de la fonction eval à altérer l'environnement de son appelant est sévèrement restreinte.

L'un des avantages du code strict est que des outils tels que YUI Compressor peuvent 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é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 des grands programmes beaucoup plus difficile et dégrade considérablement la fiabilité. Donc, en mode strict, les variables globales implicites ne sont plus créées. Vous devez déclarer explicitement toutes vos variables.

Fuite globale

Il y a un certain nombre de situations qui pourraient faire que this soit lié à l'objet global. Par exemple, si vous oubliez de fournir le new préfixe lors de l'appel d'une fonction constructeur, le constructeur sera lié de manière inattendue à l'objet global. Ainsi, au lieu d'initialiser un nouvel objet, il modifiera les variables globales. Dans ces situations, le mode strict liera à la place undefined , ce qui forcera le constructeur à lancer une exception à la place, permettant ainsi de détecter l'erreur 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 tant que la fonction Object.createProperty d'ES5 Object.createProperty cette fonctionnalité. Si vous avez tenté d'attribuer 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 procéderait comme s'il l'avait fait. C'est un risque d'intégrité qui peut amener les programmes à entrer dans un état incohérent. En mode strict, la tentative de modification d'une 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 la taille des mots était multiple de 3. Vous aviez besoin d'octal lorsque vous utilisiez l'unité centrale CDC 6600 avec un mot de 60 bits. Si vous pouviez lire octal, vous pourriez regarder un mot comme 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'octalitude a été sélectionnée: Leading zero. Donc, en C, 0100 signifie 64, pas 100, et 08 est une erreur, pas 8. Plus malheureusement, cet anachronisme a été copié dans presque toutes les langues modernes, y compris JavaScript, où il sert uniquement à créer des erreurs. Il n'a pas d'autre but. Donc, en mode strict, les formes octales ne sont plus autorisées.

Etc

Les arguments pseudo-array deviennent un peu plus semblables à des tableaux dans ES5. En mode strict, il perd ses propriétés d' caller et d' caller . Cela permet de passer vos arguments à un code non fiable sans pour autant abandonner beaucoup de contexte confidentiel. De plus, la propriété arguments des fonctions est éliminée.

En mode strict, les clés dupliquées 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 une variable avec le même nom que l'un de ses paramètres. Une fonction ne peut pas delete ses propres variables. Une tentative de delete une propriété non configurable renvoie désormais une exception. Les valeurs primitives ne sont pas implicitement enveloppé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




When adding "use strict"; , the following cases will throw a SyntaxError before the script is executing:

  • Paving the way for future ECMAScript versions , using one of the newly reserved keywords (in prevision for ECMAScript 6 ): implements , interface , let , package , private , protected , public , static , and yield .

  • Declaring function in blocks

    if(a<b){ function f(){} }
    
  • Octal syntax

    var n = 023;
    
  • this point to the global object.

     function f() {
          "use strict";
          this.a = 1;
     };
     f(); 
    
  • Declaring twice the same name for a property name in an object literal

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

    This is no longer the case in ECMAScript 6 ( bug 1041128 ).

  • Declaring two function arguments with the same name function

    f(a, b, b){}
    
  • Setting a value to an undeclared variable

    function f(x){
       "use strict";
       var a = 12;
       b = a + x*35; // error!
    }
    f();
    
  • Using delete on a variable name delete myVariable;

  • Using eval or arguments as variable or function argument name

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

Sources:




There's a good talk by some people who were on the ECMAScript committee: Changes to JavaScript, Part 1: ECMAScript 5" about how incremental use of the "use strict" switch allows JavaScript implementers to clean up a lot of the dangerous features of JavaScript without suddenly breaking every website in the world.

Of course it also talks about just what a lot of those misfeatures are (were) and how ECMAScript 5 fixes them.




Si vous utilisez un navigateur publié au cours de la dernière année, il est très probable que le mode JavaScript strict soit supporté. Seuls les anciens navigateurs qui existaient avant ECMAScript 5 sont devenus la norme actuelle et ne la prennent pas en charge.

Les guillemets autour de la commande s'assurent 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 de manière difficile à détecter dans les anciens navigateurs).




Links