¿Qué es el "modo estricto" y cómo se utiliza?

134

He estado buscando la referencia de JavaScript en la red de desarrolladores de Mozilla, y me encontré con algo llamado "strict mode". Lo leí y tengo problemas para entender lo que hace. ¿Alguien puede explicar brevemente (en general) cuál es su propósito y cómo es útil?

nkcmr
fuente
2
Relacionado: stackoverflow.com/q/1335851/1461424
sampathsris

Respuestas:

149

Su objetivo principal es hacer más comprobaciones.

Simplemente agregue "use strict";en la parte superior de su código, antes que nada.

Por ejemplo, blah = 33;es JavaScript válido. Significa que crea una variable completamente global blah.

Pero en modo estricto es un error porque no usó la palabra clave "var" para declarar la variable.

La mayoría de las veces no se trata de crear variables globales en el medio de un alcance arbitrario, por lo que la mayoría de las veces blah = 33escrito es un error y el programador no quería que fuera una variable global, querían decir a escribir var blah = 33.

Del mismo modo, no permite muchas cosas que son técnicamente válidas para hacer. NaN = "lol"No produce un error. Tampoco cambia el valor de NaN. El uso estricto de esto (y declaraciones extrañas similares) produce errores. La mayoría de las personas aprecian esto porque no hay razón para escribir NaN = "lol", por lo que probablemente hubo un error tipográfico.

Lea más en la página de MDN en modo estricto

Simon Sarris
fuente
44
este es un duplicado exacto de la documentación en MDN
nkcmr
23
¿Qué no entiendes sobre su utilidad entonces? Su objetivo es ayudar al desarrollo detectando cosas que son errores válidos pero muy probables.
Simon Sarris
34

Un aspecto de modo estricto no se ha mencionado en la respuesta de Simon es que el estricto Mode Sets thisa undefineden funciones invocan a través de invocación de la función.

Entonces cosas como esta

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

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

causará un error cuando privateMethodse llame (ya que no puede agregar una propiedad a undefined), en lugar de agregar una bpropiedad al objeto global de manera inútil .

Adam Rackis
fuente
44
sí necesita agregar privateMethod.bind(this)();y llamar connew jsbin.com
hlcs
Restricciones más importantes en modo estricto: docs.microsoft.com/en-us/scripting/javascript/advanced/…
Krishna Mohan
21

Se agregó el modo estricto para que hubiera un subconjunto fácilmente analizable estáticamente de EcmaScript que sería un buen objetivo para futuras versiones del lenguaje. El modo estricto también se diseñó con la esperanza de que los desarrolladores que se limitan al modo estricto cometan menos errores y que los errores que cometan se manifiesten de manera más obvia.

Harmony , que con suerte se convertirá en la próxima versión principal de EcmaScript, se construirá sobre ES5 estricto.

Harmony se basa en el modo estricto ES5 para evitar demasiados modos.

Algunos otros experimentos de idiomas también dependen del modo estricto. SES depende de la capacidad de análisis del modo estricto ES5.

Experimento de diseño SES (Secure ECMAScript)

Diseñe un lenguaje de programación de capacidad de objetos eliminando o reparando funciones en ES5 / Strict.

Debe haber una traducción directa de SES a ES5 / Strict.

El Anexo C de la norma explica las diferencias entre el modo estricto y el modo normal.

El modo estricto de restricción y excepciones

  • Los identificadores "implementos", "interfaz", "let", "paquete", "privado", "protegido", "público", "estático" y "rendimiento" se clasifican como tokens FutureReservedWord dentro del código de modo estricto. (7.6.12 [?]).
  • Una implementación conforme, al procesar código de modo estricto, puede no extender la sintaxis de NumericLiteral (7.8.3) para incluir OctalIntegerLiteral como se describe en B.1.1.
  • Una implementación conforme, al procesar código de modo estricto (ver 10.1.1), no puede extender la sintaxis de EscapeSequence para incluir OctalEscapeSequence como se describe en B.1.2.
  • La asignación a un identificador no declarado o referencia irresoluble no crea una propiedad en el objeto global. Cuando se produce una asignación simple dentro del código de modo estricto, su LeftHandSide no debe evaluar una referencia irresoluble. Si lo hace, se genera una excepción ReferenceError (8.7.2). El LeftHandSide tampoco puede ser una referencia a una propiedad de datos con el valor de atributo {[[Writable]]: false}, a una propiedad de acceso con el valor de atributo {[[Set]]: undefined}, ni a una inexistente propiedad de un objeto cuya propiedad interna [[Extensible]] tiene el valor falso. En estos casos, se produce una excepción TypeError (11.13.1).
  • El identificador eval o los argumentos pueden no aparecer como LeftHandSideExpression de un operador de asignación (11.13) o de una PostfixExpression (11.3) o como la UnaryExpression operada por un operador de incremento de prefijo (11.4.4) o un decremento de prefijo (11.4.5) . Los objetos de argumentos para funciones de modo estricto definen propiedades de acceso no configurables llamadas "llamador" y "llamante" que arrojan una excepción TypeError en el acceso (10.6).
  • Los objetos de argumentos para funciones de modo estricto no comparten dinámicamente sus valores de propiedad indexados de matriz con los enlaces de parámetros formales correspondientes de sus funciones. (10.6) Para funciones de modo estricto, si se crea un objeto de argumentos, el enlace de los argumentos del identificador local al objeto de argumentos es inmutable y, por lo tanto, puede no ser el objetivo de una expresión de asignación. (10.5)
  • Es un SyntaxError si el código de modo estricto contiene un ObjectLiteral con más de una definición de cualquier propiedad de datos (11.1.5). Es un SyntaxError si el identificador "eval" o los "argumentos" del identificador se producen como el identificador en un PropertySetParameterList de un PropertyAssignment contenido en un código estricto o si su FunctionBody es un código estricto (11.1.5).
  • El código de evaluación en modo estricto no puede crear instancias de variables o funciones en el entorno variable de la persona que llama para evaluar. En cambio, se crea un nuevo entorno variable y ese entorno se utiliza para la creación de instancias de enlace de declaración para el código de evaluación (10.4.2).
  • Si esto se evalúa dentro del código de modo estricto, entonces este valor no se coacciona a un objeto. A este valor de nulo o indefinido no se convierte en el objeto global y los valores primitivos no se convierten en objetos envolventes. El valor de este pasado a través de una llamada de función (incluidas las llamadas realizadas con Function.prototype.apply y Function.prototype.call) no coacciona el valor pasado a un objeto (10.4.3, 11.1.1, 15.3.4.3, 15.3. 4.4)
  • Cuando se produce un operador de eliminación dentro del código de modo estricto, se produce un SyntaxError si su UnaryExpression es una referencia directa a una variable, argumento de función o nombre de función (11.4.1).
  • Cuando se produce un operador de eliminación dentro del código de modo estricto, se genera un error de tipo si la propiedad que se va a eliminar tiene el atributo {[[Configurable]]: falso} (11.4.1). Es un SyntaxError si ocurre una VariableDeclaration o VariableDeclarationNoIn dentro del código estricto y su Identificador es eval o argumentos (12.2.1).
  • El código de modo estricto no puede incluir un WithStatement. La aparición de un WithStatement en dicho contexto es un SyntaxError (12.10).
  • Es un SyntaxError si un TryStatement con un Catch ocurre dentro de un código estricto y el Identificador de la producción de Catch es eval o argumentos (12.14.1)
  • Es un SyntaxError si el identificador eval o los argumentos aparecen dentro de una FormalParameterList de un modo estricto FunctionDeclaration o FunctionExpression (13.1)
  • Una función de modo estricto puede no tener dos o más parámetros formales que tengan el mismo nombre. Un intento de crear dicha función utilizando un constructor FunctionDeclaration, FunctionExpression o Function es un SyntaxError (13.1, 15.3.2).
  • Una implementación no puede extender, más allá de lo definido en esta especificación, significados dentro de funciones de modo estricto de propiedades llamadas llamador o argumentos de instancias de función. El código ECMAScript no puede crear o modificar propiedades con estos nombres en los objetos de función que corresponden a funciones de modo estricto (10.6, 13.2, 15.3.4.5.3).
  • Es un SyntaxError usar dentro del código de modo estricto los identificadores eval o los argumentos como el Identificador de una Declaración de Función o Expresión de Función o como un nombre de parámetro formal (13.1). Intentar definir dinámicamente una función de modo tan estricto utilizando el constructor de funciones (15.3.2) generará una excepción SyntaxError.
Mike Samuel
fuente
6

ECMAScript 5 introdujo el concepto de modo estricto .

Invocación de modo estricto en código

El modo estricto se aplica a scripts completos o a funciones individuales. No se aplica a la declaración de bloque encerrada entre {} llaves, intentar aplicarla a dichos contextos no hace nada.

Guión completo:

Digamos que estamos creando app.js, por lo que agregar el script de uso de la primera instrucción impondrá el modo estricto para todo el código.

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

Modo estricto para la función:

Para invocar el modo estricto para una función, ponga la declaración exacta "use estricto"; en el inicio del cuerpo de la función antes de cualquier otra declaración.

function yourFunc(){
 "use strict";

 // Your function code logic
}

El modo estricto incorpora varios cambios a la semántica normal de Javascript. El primer modo estricto elimina algunos errores silenciosos de JavaScript cambiándolos para arrojar errores.

Por ejemplo: código usando el modo estricto

ingrese la descripción de la imagen aquí

En el ejemplo de código anterior sin usar el modo estricto en el código, no arrojará un error. Como estamos accediendo a la variable xsin declararla. Entonces, en modo estricto, el acceso a la variable no declarada arroja un error.

Ahora intentemos acceder a la variable x sin declararla sin el modo estricto.

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

// Will not throw an error

Ventaja de usar el modo estricto:

  • Elimine los errores silenciosos de JavaScript lanzando el error.
  • Soluciona errores que dificultan que el motor de JavaScript realice la optimización.
  • Haga que el código se ejecute más rápido en algún momento que el código idéntico que no está en modo estricto
  • Prohíbe que se defina alguna sintaxis en una versión futura de ECMAScript.
Nishant Kumar
fuente
5

El modo estricto realiza varios cambios en la semántica de JavaScript normal.

  • el modo estricto elimina algunos errores silenciosos de JavaScript al cambiarlos para arrojar errores.

  • El modo estricto corrige errores que dificultan que los motores de JavaScript realicen optimizaciones.

  • el modo estricto prohíbe que se defina cierta sintaxis en futuras versiones de ECMAScript.

Renganathan MG
fuente
1

ECMAScript5 introduce algunos objetos y propiedades nuevos y también los llamados "strict mode" .

El modo estricto es un subconjunto del lenguaje que excluye características obsoletas. El modo estricto es opcional y no es obligatorio, lo que significa que si desea que su código se ejecute en el modo estricto, declara su intención utilizando (una vez por función o una vez para todo el programa) la siguiente cadena:

"use strict";
Vahid Hallaji
fuente
1

2017 y finalmente encontré la documentación:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

El modo estricto es una forma de optar por una variante restringida de JavaScript. El modo estricto no es solo un subconjunto: intencionalmente tiene una semántica diferente del código normal. Los navegadores que no admiten el modo estricto ejecutarán un código de modo estricto con un comportamiento diferente al de los navegadores que sí lo hacen, así que no confíe en el modo estricto sin pruebas de características para obtener soporte para los aspectos relevantes del modo estricto. El código de modo estricto y el código de modo no estricto pueden coexistir, por lo que los scripts pueden optar por el modo estricto de forma incremental.


El modo estricto realiza varios cambios en la semántica de JavaScript normal. Primero, el modo estricto elimina algunos errores silenciosos de JavaScript al cambiarlos para arrojar errores. En segundo lugar, el modo estricto corrige errores que dificultan que los motores de JavaScript realicen optimizaciones: a veces se puede hacer que el código de modo estricto se ejecute más rápido que el código idéntico que no es el modo estricto. En tercer lugar, el modo estricto prohíbe que se defina cierta sintaxis en futuras versiones de ECMAScript.

Tilak Maddy
fuente
0

Pregunta: El
siguiente es el problema que encontré, estaba siguiendo un tutorial y terminé intentando compilar el siguiente scssarchivo e intentando generar código CSS a partir de él,

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

usando la siguiente gulpfile.jstarea:

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'))
});

Entonces el error que obtengo es el siguiente:

~/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...

Solución:
Entonces me muestra el index.jsarchivo que está dentro de mi módulo gulp-sass (que está básicamente bloqueado y no debe editarse). Pero si voy con fuerza y ​​agrego el "use_strict"en la parte superior de ese index.jsarchivo, ejecuta mi tarea sin problemas.

Estaba indefenso, ¡así que sigo usando esto como la solución! Pero luego de pasar por otras preguntas y respuestas sobre SO , vi la siguiente respuesta de la siguiente manera:

sudo npm install -g n
sudo n stable

y antes actualicé mis NodeJs (a Version10.x), y luego reconstruí Gulp ejecutando los siguientes comandos como Terminal me indicó:

npm rebuild node-sass --force

Y todo está bien. Así es como se resolvió. Deshice los cambios que hice para el index.jsarchivo del módulo gulp. Y ahora funciona sin problemas.

¡Espero que esta respuesta sea útil para alguien por ahí!

Randika Vishman
fuente