qu'est-ce que le «mode strict» et comment est-il utilisé?

134

J'ai regardé la référence JavaScript sur le Mozilla Developer Network, et je suis tombé sur quelque chose qui s'appelle "strict mode". Je l'ai relu et j'ai du mal à comprendre ce qu'il fait. Quelqu'un peut-il expliquer brièvement (en général) quel est son objectif et en quoi il est utile?

nkcmr
la source
2
En relation: stackoverflow.com/q/1335851/1461424
sampathsris

Réponses:

149

Son objectif principal est de faire plus de vérifications.

Ajoutez simplement "use strict";en haut de votre code, avant toute autre chose.

Par exemple, blah = 33;est un JavaScript valide. Cela signifie que vous créez une variable complètement globale blah.

Mais en mode strict, c'est une erreur car vous n'avez pas utilisé le mot-clé "var" pour déclarer la variable.

La plupart du temps, vous ne voulez pas créer de variables globales au milieu d'une portée arbitraire, donc la plupart du temps, blah = 33il s'agit d'une erreur et le programmeur ne voulait pas en fait que ce soit une variable globale, ils voulaient dire écrire var blah = 33.

De même, il interdit de faire beaucoup de choses qui sont techniquement valables. NaN = "lol"ne produit pas d'erreur. Cela ne change pas non plus la valeur de NaN. en utilisant strict this (et des déclarations étranges similaires) produisent des erreurs. La plupart des gens apprécient cela car il n'y a aucune raison d'écrire NaN = "lol", donc il y avait très probablement une faute de frappe.

En savoir plus sur la page MDN sur le mode strict

Simon Sarris
la source
4
il s'agit d'une copie exacte de la documentation sur MDN
nkcmr
23
Que ne comprenez-vous donc pas à propos de son utilité? Il vise à aider le développement en détectant les choses qui sont des erreurs valides mais les plus probables.
Simon Sarris
34

Un aspect du mode strict non déjà mentionné dans la réponse de Simon est que le mode strict est défini thissurundefined des fonctions invoquées par appel de fonction.

Alors des choses comme ça

function Obj() {
   this.a = 12;
   this.b = "a";
   this.privilegedMethod = function () {
      this.a++;
      privateMethod();
   };

   function privateMethod() {
     this.b = "foo";
   }
}

provoquera une erreur lors de l' privateMethodappel (car vous ne pouvez pas ajouter de propriété à undefined), plutôt que d'ajouter inutilement une bpropriété à l'objet global.

Adam Rackis
la source
4
ouais besoin d'ajouter privateMethod.bind(this)();et d'appeler avecnew jsbin.com
hlcs
Restrictions les plus importantes en mode strict: docs.microsoft.com/en-us/scripting/javascript/advanced/…
Krishna Mohan
21

Le mode strict a été ajouté afin qu'il y ait un sous-ensemble facilement analysable statiquement d'EcmaScript qui serait une bonne cible pour les futures versions du langage. Le mode strict a également été conçu dans l'espoir que les développeurs qui se limitent au mode strict feraient moins d'erreurs et que les bogues qu'ils commettent se manifesteraient de manière plus évidente.

Harmony , qui, espérons-le, deviendra la prochaine version majeure d'EcmaScript, sera construite sur ES5 strict.

Harmony s'appuie sur le mode strict ES5 pour éviter un trop grand nombre de modes.

Certaines autres expériences linguistiques dépendent également du mode strict. SES dépend de l'analysabilité du mode strict ES5.

Expérience de conception SES (Secure ECMAScript)

Concevez un langage de programmation de capacité objet en supprimant ou en réparant des fonctionnalités dans ES5 / Strict.

Il devrait y avoir une traduction simple de SES à ES5 / Strict.

L'annexe C de la norme explique les différences entre le mode strict et le mode normal.

La restriction et les exceptions du mode strict

  • Les identificateurs "implements", "interface", "let", "package", "private", "protected", "public", "static" et "yield" sont classés comme des jetons FutureReservedWord dans un code en mode strict. (7.6.12 [?]).
  • Une implémentation conforme, lors du traitement d'un code en mode strict, ne peut pas étendre la syntaxe de NumericLiteral (7.8.3) pour inclure OctalIntegerLiteral comme décrit au B.1.1.
  • Une implémentation conforme, lors du traitement de code en mode strict (voir 10.1.1), ne peut pas étendre la syntaxe de EscapeSequence pour inclure OctalEscapeSequence comme décrit au B.1.2.
  • L'attribution à un identificateur non déclaré ou à une référence autrement impossible à résoudre ne crée pas de propriété dans l'objet global. Lorsqu'une affectation simple se produit dans un code en mode strict, son LeftHandSide ne doit pas être évalué comme une référence impossible à résoudre. Si c'est le cas, une exception ReferenceError est lancée (8.7.2). Le LeftHandSide peut également ne pas être une référence à une propriété de données avec la valeur d'attribut {[[Writable]]: false}, à une propriété d'accesseur avec la valeur d'attribut {[[Set]]: undefined}, ni à un inexistant propriété d'un objet dont la propriété interne [[Extensible]] a la valeur false. Dans ces cas, une exception TypeError est levée (11.13.1).
  • L'identifiant eval ou les arguments peuvent ne pas apparaître comme LeftHandSideExpression d'un opérateur Assignment (11.13) ou d'une PostfixExpression (11.3) ou comme UnaryExpression opérée par un opérateur Prefix Increment (11.4.4) ou Prefix Decrement (11.4.5) . Les objets d'arguments pour les fonctions en mode strict définissent des propriétés d'accesseur non configurables nommées "caller" et "callee" qui lèvent une exception TypeError lors de l'accès (10.6).
  • Les objets Arguments pour les fonctions en mode strict ne partagent pas dynamiquement leurs valeurs de propriété indexées par tableau avec les liaisons de paramètres formels correspondantes de leurs fonctions. (10,6). Pour les fonctions en mode strict, si un objet arguments est créé, la liaison des arguments d'identificateur local à l'objet arguments est immuable et ne peut donc pas être la cible d'une expression d'affectation. (10,5).
  • Il s'agit d'une SyntaxError si le code en mode strict contient un ObjectLiteral avec plus d'une définition de n'importe quelle propriété de données (11.1.5). C'est une SyntaxError si l'identificateur "eval" ou l'identificateur "arguments" apparaît comme l'identificateur dans un PropertySetParameterList d'un PropertyAssignment contenu dans un code strict ou si son FunctionBody est un code strict (11.1.5).
  • Le code eval en mode strict ne peut pas instancier des variables ou des fonctions dans l'environnement variable de l'appelant à eval. Au lieu de cela, un nouvel environnement de variable est créé et cet environnement est utilisé pour l'instanciation de liaison de déclaration pour le code eval (10.4.2).
  • Si cela est évalué dans un code de mode strict, la valeur this n'est pas forcée à un objet. Une valeur null ou non définie n'est pas convertie en objet global et les valeurs primitives ne sont pas converties en objets wrapper. Cette valeur transmise via un appel de fonction (y compris les appels effectués à l'aide de Function.prototype.apply et Function.prototype.call) ne contraint pas la transmission de cette valeur à un objet (10.4.3, 11.1.1, 15.3.4.3, 15.3. 4.4).
  • Lorsqu'un opérateur de suppression se produit dans un code en mode strict, une SyntaxError est levée si son UnaryExpression est une référence directe à une variable, un argument de fonction ou un nom de fonction (11.4.1).
  • Lorsqu'un opérateur de suppression se produit dans un code de mode strict, une TypeError est levée si la propriété à supprimer a l'attribut {[[Configurable]]: false} (11.4.1). C'est une SyntaxError si un VariableDeclaration ou VariableDeclarationNoIn se produit dans un code strict et que son identificateur est eval ou arguments (12.2.1).
  • Le code de mode strict peut ne pas inclure de WithStatement. L'occurrence d'un WithStatement dans un tel contexte est une SyntaxError (12.10).
  • C'est une SyntaxError si un TryStatement avec un Catch se produit dans un code strict et que l'identifiant de la production de Catch est eval ou arguments (12.14.1)
  • C'est une SyntaxError si l'identifiant eval ou arguments apparaît dans une FormalParameterList d'une FunctionDeclaration ou FunctionExpression en mode strict (13.1)
  • Une fonction en mode strict peut ne pas avoir deux ou plusieurs paramètres formels portant le même nom. Une tentative de création d'une telle fonction à l'aide d'un constructeur FunctionDeclaration, FunctionExpression ou Function est une SyntaxError (13.1, 15.3.2).
  • Une implémentation ne peut pas étendre, au-delà de ce qui est défini dans cette spécification, les significations au sein des fonctions en mode strict des propriétés appelées ou des arguments des instances de fonction. Le code ECMAScript ne peut pas créer ou modifier des propriétés avec ces noms sur des objets de fonction qui correspondent à des fonctions en mode strict (10.6, 13.2, 15.3.4.5.3).
  • C'est une SyntaxError à utiliser dans un code de mode strict les identifiants eval ou arguments comme identifiant d'une FunctionDeclaration ou FunctionExpression ou comme nom de paramètre formel (13.1). Tenter de définir dynamiquement une telle fonction en mode strict à l'aide du constructeur Function (15.3.2) lèvera une exception SyntaxError.
Mike Samuel
la source
6

ECMAScript 5 a introduit le concept de mode strict .

Appel du mode strict dans le code

Le mode strict s'applique à des scripts entiers ou à une fonction individuelle. Cela ne s'applique pas aux instructions de bloc entre accolades {}, tenter de l'appliquer à de tels contextes ne fait rien.

Script entier:

Supposons que nous créons app.js, donc l'ajout du premier script d'utilisation d'instruction appliquera le mode strict pour tout le code.

// app.js whole script in strict mode syntax
use strict”;
// Now you can start writing your code 

Mode strict pour la fonction:

Pour appeler le mode strict pour une fonction, mettez l'instruction exacte «use strict»; au début du corps de la fonction avant toute autre instruction.

function yourFunc(){
 "use strict";

 // Your function code logic
}

Le mode strict intègre plusieurs changements à la sémantique Javascript normale. Le premier mode strict élimine certaines erreurs silencieuses JavaScript en les changeant pour générer des erreurs.

Par exemple: code utilisant le mode strict

entrez la description de l'image ici

Dans l'exemple de code ci-dessus sans utiliser le mode strict dans le code, cela ne générera pas d'erreur. Comme nous accédons à la variable xsans la déclarer. Donc, en mode strict, l'accès à une variable non déclarée génère une erreur.

Essayons maintenant d'accéder à la variable x sans la déclarer sans mode strict.

(function(){
    x = 3;
})();

// Will not throw an error

Avantage d'utiliser le mode strict:

  • Éliminez les erreurs silencieuses JavaScript en lançant une erreur.
  • Corrige l'erreur qui rendait difficile l'optimisation du moteur JavaScript.
  • Rendre le code plus rapide parfois qu'un code identique qui n'est pas en mode strict
  • Interdit certaines syntaxes susceptibles d'être définies dans la future version d'ECMAScript.
Nishant Kumar
la source
5

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

  • Le mode strict élimine certaines erreurs JavaScript silencieuses en les changeant en erreurs.

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

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

Renganathan MG
la source
1

ECMAScript5 introduit de nouveaux objets et propriétés ainsi que le soi-disant "strict mode" .

Le mode strict est un sous-ensemble du langage qui exclut les fonctionnalités obsolètes. Le mode strict est opt-in et n'est pas obligatoire, ce qui signifie que si vous voulez que votre code s'exécute en mode strict, vous déclarez votre intention en utilisant (une fois par fonction, ou une fois pour l'ensemble du programme) la chaîne suivante:

"use strict";
Vahid Hallaji
la source
1

2017 et j'ai enfin trouvé la documentation:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

Le mode strict est un moyen d'accepter une variante restreinte de JavaScript. Le mode strict n'est pas seulement un sous-ensemble: il a intentionnellement une sémantique différente du code normal. Les navigateurs ne prenant pas en charge le mode strict exécuteront du code en mode strict avec un comportement différent de celui des navigateurs qui le font, alors ne comptez pas sur le mode strict sans test de fonctionnalités pour la prise en charge des aspects pertinents du mode strict. Le code en mode strict et le code en mode non strict peuvent coexister, de sorte que les scripts peuvent opter pour le mode strict de manière incrémentielle.


Le mode strict apporte plusieurs modifications à la sémantique JavaScript normale. Premièrement, le mode strict élimine certaines erreurs silencieuses JavaScript en les modifiant pour générer des erreurs. Deuxièmement, le mode strict corrige des erreurs qui empêchent les moteurs JavaScript d'effectuer des optimisations: le code en mode strict peut parfois être amené à s'exécuter plus rapidement qu'un code identique qui n'est pas en mode strict. Troisièmement, le mode strict interdit certaines syntaxes susceptibles d'être définies dans les futures versions d'ECMAScript.

Tilak Maddy
la source
0

Question:
Voici le problème que j'ai rencontré, je suivais un tutoriel et il a fini par essayer de compiler le scssfichier suivant et d'essayer de générer du code CSS à partir de celui-ci,

.fatty{
  width: percentage(6/7);
}

en utilisant la gulpfile.jstâche suivante :

var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('sass', function () {
    return gulp.src('app/scss/styles.scss')
        .pipe(sass())
        .pipe(gulp.dest('app/css'))
});

Donc, l'erreur que j'obtiens est la suivante:

~/htdocs/Learning/gulp1/node_modules/gulp-sass/index.js:66
    let sassMap;
    ^^^

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:373:25)
// stacktrace here...

Solution:
il me montre donc le index.jsfichier qui se trouve dans mon module gulp-sass (qui est fondamentalement verrouillé et ne doit pas être modifié). Mais si je vais avec force et ajoute "use_strict"le dessusindex.js fichier, il exécute ma tâche en douceur.

J'étais impuissant, alors je continue à utiliser ceci comme solution! Mais après avoir parcouru d'autres questions et réponses SO , j'ai vu la réponse suivante:

sudo npm install -g n
sudo n stable

et plus tôt, j'ai mis à jour mes NodeJs (vers Version10.x), puis j'ai reconstruit Gulp en exécutant les commandes suivantes comme Terminal me l'a indiqué:

npm rebuild node-sass --force

Et tout va bien. C'est ainsi que cela a été résolu. J'ai annulé les changements que j'ai faits pourindex.js fichier du module gulp. Et maintenant, il fonctionne bien.

J'espère que cette réponse sera utile à quelqu'un là-bas!

Randika Vishman
la source