¿Qué hace "use strict" en JavaScript, y cuál es el razonamiento detrás de esto?



Answers

Es una nueva característica de ECMAScript 5. John Resig escribió un buen resumen de ello.

Es solo una cadena que coloca en sus archivos JavaScript (ya sea en la parte superior de su archivo o dentro de una función) que se ve así:

"use strict";

Ponerlo en su código ahora no debería causar ningún problema con los navegadores actuales ya que solo es una cadena. Puede causar problemas con su código en el futuro si su código viola el pragma. Por ejemplo, si actualmente tiene foo = "bar" sin definir foo primero, su código comenzará a fallar ... lo cual es bueno en mi opinión.

Question

Recientemente, ejecuté algunos de mis códigos JavaScript a través de JSLint , y me dio el siguiente error:

Problema en la línea 1 caracter 1: Falta la instrucción "use strict".

Al hacer algunas búsquedas, me di cuenta de que algunas personas agregan "use strict"; en su código de JavaScript. Una vez que agregué la declaración, el error dejó de aparecer. Desafortunadamente, Google no reveló gran parte de la historia detrás de esta declaración de cadena. Ciertamente debe tener algo que ver con la forma en que el navegador interpreta el JavaScript, pero no tengo idea de cuál sería el efecto.

Entonces, ¿qué es "use strict"; sobre todo, ¿qué implica, y sigue siendo relevante?

¿Alguno de los navegadores actuales responde al "use strict"; cadena o es para uso futuro?




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
    errores

  • 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.




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.




Usando 'use strict'; de repente no mejora tu código.

El modo estricto JavaScript es una característica en ECMAScript 5 . Puede habilitar el modo estricto declarando esto en la parte superior de su script / función.

'use strict';

Cuando un motor de JavaScript ve esta directiva , comenzará a interpretar el código en un modo especial. En este modo, se producen errores cuando se detectan ciertas prácticas de codificación que podrían terminar siendo errores potenciales (que es el razonamiento detrás del modo estricto).

Considera este ejemplo:

var a = 365;
var b = 030;

En su obsesión por alinear los literales numéricos, el desarrollador inicializó inadvertidamente la variable b con un literal octal. El modo no estricto interpretará esto como un literal numérico con valor 24 (en la base 10). Sin embargo, el modo estricto arrojará un error.

Para una lista no exhaustiva de especialidades en modo estricto, vea esta respuesta .

¿Dónde debería usar 'use strict'; ?

  • En mi nueva aplicación de JavaScript: ¡Absolutamente! El modo estricto se puede usar como denunciante cuando estás haciendo algo estúpido con tu código.

  • En mi código JavaScript existente : ¡ Probablemente no! Si su código JavaScript existente tiene instrucciones que están prohibidas en modo estricto, la aplicación simplemente se romperá. Si desea el modo estricto, debe estar preparado para depurar y corregir su código existente. Es por eso que usar 'use strict'; de repente no mejora tu código .

¿Cómo uso el modo estricto?

  1. Inserta un 'use strict'; declaración en la parte superior de su secuencia de comandos:

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

    Tenga en cuenta que todo en el archivo myscript.js se interpretará en modo estricto.

  2. O bien, inserte un 'use strict'; declaración en la parte superior de su cuerpo de función:

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

    Todo en el alcance léxico de la función doSomething se interpretará en modo estricto. La palabra alcance léxico es importante aquí. Vea esta respuesta para una mejor explicación.

¿Qué cosas están prohibidas en el modo estricto?

Encontré un buen artículo que describe varias cosas que están prohibidas en modo estricto (tenga en cuenta que esta no es una lista exclusiva):

Alcance

Históricamente, JavaScript se ha confundido acerca de cómo se definen las funciones. A veces parecen tener un alcance estático, pero algunas características hacen que se comporten como si tuvieran un alcance dinámico. Esto es confuso y hace que los programas sean difíciles de leer y comprender. El malentendido causa errores. También es un problema para el rendimiento. El alcance estático permitiría el enlace variable en tiempo de compilación, pero el requisito de alcance dinámico significa que el enlace debe diferirse al tiempo de ejecución, lo que implica una importante penalización del rendimiento.

El modo estricto requiere que todas las vinculaciones variables se realicen de forma estática. Eso significa que las características que previamente requerían enlace dinámico deben ser eliminadas o modificadas. Específicamente, se elimina la declaración con, y la capacidad de la función de evaluación para alterar el entorno de la persona que llama está severamente restringida.

Uno de los beneficios del código estricto es que herramientas como YUI Compressor pueden hacer un mejor trabajo al procesarlo.

Variables globales implícitas

JavaScript ha implicado variables globales. Si no declara explícitamente una variable, se declara implícitamente una variable global para usted. Esto facilita la programación a los principiantes porque pueden descuidar algunas de sus tareas domésticas básicas. Pero hace que la administración de programas más grandes sea mucho más difícil y degrada significativamente la confiabilidad. Entonces, en modo estricto, las variables globales implícitas ya no se crean. Debería declarar explícitamente todas sus variables.

Fuga global

Hay una serie de situaciones que podrían hacer que this se vincule al objeto global. Por ejemplo, si olvida proporcionar el new prefijo al llamar a una función de constructor, this del constructor se vinculará de forma inesperada con el objeto global, por lo que en lugar de inicializar un nuevo objeto, en lugar de eso se manipulará silenciosamente las variables globales. En estas situaciones, el modo estricto vinculará this a undefined , lo que hará que el constructor genere una excepción, lo que permite detectar el error mucho antes.

Error ruidoso

JavaScript siempre ha tenido propiedades de solo lectura, pero no pudo crearlas usted mismo hasta que la función Object.createProperty de ES5 expuso esa capacidad. Si intentó asignar un valor a una propiedad de solo lectura, fallaría en silencio. La asignación no cambiaría el valor de la propiedad, pero su programa procedería como si lo hubiera hecho. Este es un peligro de integridad que puede causar que los programas entren en un estado inconsistente. En modo estricto, intentar cambiar una propiedad de solo lectura generará una excepción.

Octal

La representación octal (o base 8) de los números era extremadamente útil cuando se hacía una programación a nivel de máquina en máquinas cuyo tamaño de palabra era un múltiplo de 3. Necesitabas octal cuando trabajabas con el mainframe CDC 6600, que tenía un tamaño de palabra de 60 bits. Si pudieras leer octal, podrías ver una palabra como 20 dígitos. Dos dígitos representaban el código de operación, y un dígito identificó uno de los 8 registros. Durante la transición lenta de los códigos de máquina a los lenguajes de alto nivel, se pensó que era útil proporcionar formas octales en los lenguajes de programación.

En C, se seleccionó una representación extremadamente desafortunada de octalness: Leading zero. Entonces, en C, 0100 significa 64, no 100 y 08 es un error, no 8. Aún más desafortunadamente, este anacronismo ha sido copiado en casi todos los idiomas modernos, incluido JavaScript, donde solo se usa para crear errores. No tiene otro propósito. Entonces, en modo estricto, las formas octales ya no están permitidas.

Etcétera

Los argumentos pseudo array se vuelven un poco más parecidos a un array en ES5. En modo estricto, pierde sus propiedades callee y caller . Esto hace posible pasar sus arguments al código que no es de confianza sin renunciar a un montón de contexto confidencial. Además, se elimina la propiedad arguments de las funciones.

En modo estricto, las claves duplicadas en un literal de función producirán un error de sintaxis. Una función no puede tener dos parámetros con el mismo nombre. Una función no puede tener una variable con el mismo nombre que uno de sus parámetros. Una función no puede delete sus propias variables. Un intento de delete una propiedad no configurable ahora arroja una excepción. Los valores primitivos no están envueltos implícitamente.

Palabras reservadas para futuras versiones de JavaScript

ECMAScript 5 agrega una lista de palabras reservadas. Si los usa como variables o argumentos, el modo estricto lanzará un error. Las palabras reservadas son:

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

Otras lecturas




Si a las personas les preocupa utilizar el use strict , vale la pena consultar este artículo:

Compatibilidad con ECMAScript 5 'Modo estricto' en navegadores. ¿Qué significa esto?
NovoGeek.com - Blog de Krishna

Habla sobre el soporte del navegador, pero lo más importante es cómo tratarlo de manera segura:

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



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. P.ej:

    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 .




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.




"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.




Si utiliza un navegador lanzado en el último año más o menos, probablemente sea compatible con el modo JavaScript estricto. Solo los navegadores más antiguos antes de que ECMAScript 5 se convirtiera en el estándar actual no lo admiten.

Las comillas alrededor del comando aseguran que el código también funcionará en los navegadores más antiguos (aunque las cosas que generan un error de sintaxis en modo estricto solo causarán mal funcionamiento del script de alguna manera difícil de detectar en esos navegadores más antiguos).




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() { } 
    

Fuentes:




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.



Me gustaría ofrecer una respuesta algo más completa que complemente las otras respuestas. Esperaba editar la respuesta más popular, pero fallé. Traté de hacerlo tan completo y completo como pude.

Puede consultar la documentación de MDN para obtener más información.

"use strict" una directiva introducida en ECMAScript 5.

Las directivas son similares a las declaraciones, pero diferentes.

  • use strict no contiene palabras clave: La directiva es una declaración de expresión simple, que consiste en un literal de cadena especial (en comillas simples o dobles). Los motores de JavaScript, que no implementan ECMAScript 5, simplemente ven una declaración de expresión sin efectos secundarios. Se espera que las versiones futuras de las normas ECMAScript introduzcan el use como una palabra clave real; las citas se volverían obsoletas.
  • use strict se puede usar solo al comienzo de un script o de una función, es decir, debe preceder a cualquier otro enunciado (real). No tiene que ser la primera instrucción en un script de función: puede estar precedida por otras expresiones de declaración que consisten en literales de cadena (y las implementaciones de JavaScript pueden tratarlas como directivas específicas de implementación). Los enunciados de cadenas de literales, que siguen una primera declaración real (en un guión o función) son enunciados de expresión simple. Los intérpretes no deben interpretarlos como directivas y no tienen ningún efecto.

La directiva de use strict indica que el siguiente código (en una secuencia de comandos o una función) es un código estricto. El código en el nivel más alto de un script (código que no está en una función) se considera código estricto cuando el script contiene una directiva de use strict . El contenido de una función se considera código estricto cuando la función misma se define en un código estricto o cuando la función contiene una directiva de use strict . El código que se pasa a un método eval() se considera código estricto cuando eval() se invocó desde un código estricto o contiene el use strict directiva use strict .

El modo estricto de ECMAScript 5 es un subconjunto restringido del lenguaje JavaScript, que elimina los déficits relevantes del lenguaje y ofrece una comprobación de errores más estricta y una mayor seguridad. A continuación se enumeran las diferencias entre el modo estricto y el modo normal (de los cuales los tres primeros son particularmente importantes):

  • No puede usar la declaración with -en modo estricto.
  • En modo estricto todas las variables deben declararse: si asigna un valor a un identificador que no ha sido declarado como variable, función, parámetro de función, parámetro catch-clause o propiedad del Object global, entonces obtendrá un ReferenceError . En modo normal, el identificador se declara implícitamente como una variable global (como una propiedad del Object global)
  • En modo estricto, la palabra clave this tiene el valor undefined en las funciones que se invocaron como funciones (no como métodos). (En modo normal, this siempre apunta al Object global). Esta diferencia se puede usar para probar si una implementación admite el modo estricto:
var hasStrictMode = (function() { "use strict"; return this===undefined }());
  • Además, cuando se invoca una función con call() o se apply en modo estricto, this es exactamente el valor del primer argumento de la call() o apply() . (En modo normal, null e undefined son reemplazados por el Object global y los valores, que no son objetos, se convierten en objetos).

  • En modo estricto obtendrá un TypeError , cuando intente asignar propiedades de solo lectura o definir nuevas propiedades para un objeto no extensible. (En modo normal, ambos simplemente fallan sin mensaje de error).

  • En modo estricto, al pasar el código a eval() , no puede declarar o definir variables o funciones en el alcance de la persona que llama (como puede hacerlo en modo normal). En su lugar, se crea un nuevo alcance para eval() y las variables y funciones están dentro de ese alcance. Ese alcance se destruye después de que eval() finaliza la ejecución.
  • En modo estricto, el argumento-objeto de una función contiene una copia estática de los valores, que se pasan a esa función. En el modo normal, el argumento-objeto tiene un comportamiento algo "mágico": los elementos de la matriz y los parámetros de función nombrados hacen referencia al mismo valor.
  • En el modo estricto obtendrá un SyntaxError cuando al operador delete le sigue un identificador no calificado (una variable, función o parámetro de función). En modo normal, la expresión de delete no haría nada y se evalúa como false .
  • En modo estricto obtendrá un TypeError cuando intente eliminar una propiedad no configurable. (En modo normal, el intento simplemente falla y la expresión de delete se evalúa como false ).
  • En modo estricto, se considera un error sintáctico cuando intenta definir varias propiedades con el mismo nombre para un literal de objeto. (En modo normal no hay ningún error).
  • En modo estricto, se considera un error sintáctico cuando una declaración de función tiene múltiples parámetros con el mismo nombre. (En modo normal no hay ningún error).
  • En modo estricto, no se permiten los literales octales (estos son literales que comienzan con 0x . (En el modo normal, algunas implementaciones permiten literales octales).
  • En modo estricto, los identificadores eval y los arguments se tratan como palabras clave. No puede cambiar su valor, no puede asignarle un valor y no puede usarlos como nombres de variables, funciones, parámetros de función o identificadores de un bloque catch.
  • En modo estricto hay más restricciones sobre las posibilidades de examinar la pila de llamadas. arguments.caller y arguments.callee provocan un TypeError en una función en modo estricto. Además, algunas propiedades de llamadas y argumentos de funciones en modo estricto causan un TypeError cuando intentas leerlos.



"Usar estricto"; es un seguro que el programador no usará las propiedades flojas o malas de JavaScript. Es una guía, al igual que una regla te ayudará a hacer líneas rectas. "Usar estricto" te ayudará a hacer "codificación directa".

Aquellos que prefieren no usar reglas para hacer sus líneas seguidas generalmente terminan en esas páginas pidiendo a otros que depuren su código.

Créame. La sobrecarga es insignificante en comparación con el código mal diseñado. Doug Crockford, quien ha sido desarrollador senior de JavaScript durante varios años, tiene una publicación muy interesante aquí . Personalmente, me gusta regresar a su sitio todo el tiempo para asegurarme de no olvidar mi buena práctica.

La práctica moderna de JavaScript siempre debe evocar el "uso estricto"; pragma. La única razón por la cual el Grupo ECMA ha hecho que el modo "Estricto" sea opcional es para permitir a los programadores menos experimentados acceder a JavaScript y darles tiempo para adaptarse a las nuevas y más seguras prácticas de codificación.




Links