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


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

Problema en la línea 1 carácter 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 que 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?


6702
2017-08-26 16:10


origen


Respuestas:


Este artículo sobre el modo Javascript estricto podría interesarle: John Resig: ECMAScript 5 Strict Mode, JSON y más

Para citar algunas partes interesantes:

El modo estricto es una nueva característica de ECMAScript 5 que le permite colocar un programa o una función en un contexto operativo "estricto". Este contexto estricto impide que se tomen ciertas acciones y arroja más excepciones.

Y:

El modo estricto ayuda de dos maneras:

  • Captura algunos bloopers de codificación comunes, lanzando excepciones.
  • Evita o arroja errores cuando se toman acciones relativamente "inseguras" (como obtener acceso al objeto global).
  • Deshabilita características confusas o poco pensadas.

También tenga en cuenta que puede aplicar "modo estricto" a todo el archivo ... O puede usarlo solo para una función específica (Todavía citando el artículo de John Resig):

// Non-strict code...

(function(){
  "use strict";

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

// Non-strict code... 

Lo cual podría ser útil si tiene que mezclar código antiguo y nuevo ;-)

Entonces, supongo que es un poco como el "use strict" puedes usar en Perl (¿de ahí el nombre?): le ayuda a cometer menos errores al detectar más cosas que podrían provocar roturas.

Actualmente, es compatible con todos los principales navegadores  (bar IE 9 y abajo).


4392
2017-08-26 16:15



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

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.


1101
2017-08-26 16:14



La declaración "use strict"; indica al navegador que use el modo Estricto, que es un conjunto de funciones reducido y más seguro de JavaScript.

Lista de características (no exhaustiva)

  1. No permite las variables globales. (Capturas perdidas var declaraciones y errores tipográficos en nombres de variables)

  2. Las asignaciones de fallas silenciosas generarán un error en el modo estricto (asignando NaN = 5;)

  3. Los intentos de eliminar las propiedades no recuperables arrojarán (delete Object.prototype)

  4. Requiere que todos los nombres de propiedades en un objeto literal sean únicos (var x = {x1: "1", x1: "2"})

  5. Los nombres de los parámetros de función deben ser únicos (function sum (x, x) {...})

  6. Prohibe la sintaxis octal (var x = 023; algunos desarrolladores asumen erróneamente que un cero anterior no hace nada para cambiar el número).

  7. Prohíbe el with palabra clave

  8. eval en modo estricto no introduce nuevas variables

  9. Prohibe eliminar nombres simples (delete x;)

  10. Prohíbe el enlace o la asignación de los nombres eval y arguments de cualquier manera

  11. El modo estricto no alias las propiedades del arguments objeto con los parámetros formales. (es decir, en function sum (a,b) { return arguments[0] + b;} Esto funciona porque arguments[0] está obligado a a y así. )

  12. arguments.callee no es apoyado

[Árbitro: Modo estricto, Red de desarrolladores Mozilla]


518
2017-11-24 21:22



Si la gente está preocupada por usar use strict Vale la pena echarle un vistazo a 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.
*/

368
2017-07-15 23:25



Una palabra de advertencia, todos ustedes programadores de carga: aplicación "use strict" al código existente puede ser peligroso! Esto no es una pegatina de cara feliz que te haga sentir bien y que puedas darle una bofetada al código para hacerlo 'mejor'. Con el "use strict" pragma, el navegador lanzará repentinamente excepciones en lugares aleatorios que nunca arrojó antes simplemente porque en ese punto estás haciendo algo que JavaScript por defecto / flojo permite felizmente pero aborrece el estricto JavaScript! Es posible que en su código se oculten violaciones de rigor en las llamadas que rara vez se usan, que solo arrojarán una excepción cuando finalmente se ejecuten, por ejemplo, en el entorno de producción que utilizan los clientes que pagan.

Si vas a dar el paso, es una buena idea aplicar "use strict" junto con pruebas unitarias exhaustivas y una tarea de compilación JSHint estrictamente configurada que le dará la confianza de que no hay una esquina oscura de su módulo que explotará de forma horrible simplemente porque ha activado el modo estricto. O, hey, aquí hay otra opción: simplemente no agregue "use strict" a cualquiera de su código heredado, es probablemente más seguro de esa manera, sinceramente. DEFINITIVAMENTE NO añadir "use strict" a cualquier módulo que no sea de su propiedad o que no tenga, como módulos de terceros.

Creo que a pesar de que es un animal mortal enjaulado, "use strict" puede ser algo bueno, pero tienes que hacerlo bien. El mejor momento para ir estricto es cuando su proyecto es totalmente nuevo y está empezando desde cero. Configurar JSHint/JSLint con todas las advertencias y opciones puestas a punto tan fuerte como su equipo puede soportar, obtenga un buen sistema de compilación / prueba / afirmación du jour amañado como Grunt+Karma+Chai, y SOLO COMIENCE a marcar todos sus nuevos módulos como "use strict". Prepárese para curar muchos errores y advertencias. Asegúrese de que todos entiendan la gravedad configurando la compilación para FAIL si JSHint/JSLintproduce cualquier violación

Mi proyecto no era un proyecto totalmente nuevo cuando adopté "use strict". Como resultado, mi IDE está lleno de marcas rojas porque no tengo "use strict" en la mitad de mis módulos, y JSHint se queja de eso. Es un recordatorio para mí sobre qué refactorización debería hacer en el futuro. Mi objetivo es ser libre de marca roja debido a todos mis desaparecidos "use strict" declaraciones, pero eso es años lejos ahora.


182
2018-03-03 07:37



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

los Modo estricto de 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 esto 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, consulte esta respuesta.


Donde debería usar 'use strict';?

  • En mi nuevo 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 existente Código de JavaScript: ¡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. Esta es la razón por utilizando 'use strict'; de repente no mejora tu código.


¿Cómo uso el modo estricto?

  1. Insertar 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 será interpretado 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 será interpretado en modo estricto. La palabra alcance léxico es importante aquí. Ver esta respuesta para una mejor explicación


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

Encontre un Buen articulo describiendo varias cosas que están prohibidas en el modo estricto (tenga en cuenta que esta no es una lista exclusiva):

Alcance

Históricamente, JavaScript se ha confundido acerca de cómo funciona   tienen un alcance A veces parecen tener un alcance estático, pero algunos   las características hacen que se comporten como si tuvieran un alcance dinámico. Esto es   confuso, haciendo que los programas sean difíciles de leer y entender.   El malentendido causa errores. También es un problema para el rendimiento.   El alcance estático permitiría el enlace variable en compilación   tiempo, pero el requisito de alcance dinámico significa que el enlace debe ser   diferido a tiempo de ejecución, que viene con un rendimiento significativo   pena.

El modo estricto requiere que todas las vinculaciones variables se realicen de forma estática.   Eso significa que las características que anteriormente requerían vinculación dinámica   debe ser eliminado o modificado. Específicamente, la declaración con es   eliminado, y la capacidad de la función eval para manipular el   el entorno de quien llama está severamente restringido.

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

Variables globales implícitas

JavaScript ha implicado variables globales. Si   no declaras explícitamente una variable, una variable global es   declarado implícitamente para ti. Esto hace que la programación sea más fácil   principiantes porque pueden descuidar algunos de sus tareas domésticas básicas   quehaceres. Pero hace que la gestión de programas más grandes sea mucho más   difícil y degrada significativamente la fiabilidad. Entonces en estricto   modo, las variables globales implícitas ya no se crean. Debieras   declara explícitamente todas tus variables.

Fuga global

Hay una serie de situaciones que podrían causar this   estar ligado al objeto global. Por ejemplo, si te olvidas de   proporcionar la new prefijo al llamar a una función de constructor, el   constructor this se vinculará inesperadamente al objeto global, por lo   en lugar de inicializar un nuevo objeto, en cambio será silencioso   manipulación de variables globales. En estas situaciones, el modo estricto   en lugar de atar this a undefined, lo que hará que el constructor   lanzar una excepción, permitiendo que el error sea detectado mucho   cuanto antes.

Error ruidoso

JavaScript siempre ha tenido propiedades de solo lectura, pero   no podría crearlos tú mismo hasta que ES5 Object.createProperty   función expuesta esa capacidad. Si intentó asignar un valor   a una propiedad de solo lectura, fallaría silenciosamente. La asignación sería   no cambiar el valor de la propiedad, pero su programa procedería como   aunque lo tuvo. Este es un riesgo de integridad que puede causar que los programas   entrar en un estado inconsistente En modo estricto, tratando de cambiar una   la propiedad de solo lectura lanzará una excepción.

Octal

La representación octal (o base 8) de los números era extremadamente   útil cuando se hace programación a nivel de máquina en máquinas cuya palabra   los tamaños eran un múltiplo de 3. Necesitabas octal cuando trabajabas con el CDC   6600 mainframe, 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 representados   el código de operación, y un dígito identificó uno de los 8 registros. Durante el   transición lenta de códigos de máquina a lenguajes de alto nivel, era   se cree que es útil para proporcionar formas octales en lenguajes de programación.

En C, una representación extremadamente desafortunada de octalness era   seleccionado: cero principal. 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   tipo array en ES5. En modo estricto, pierde su callee y caller   propiedades. Esto hace posible pasar su arguments desconfiado   código sin renunciar a un montón de contexto confidencial. También el    arguments la propiedad de las funciones se elimina.

En modo estricto, las claves duplicadas en un literal de función producirán una   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 una 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. Primitivo   los valores 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, staticy yield


Otras lecturas


131
2018-01-29 11:35



Recomiendo encarecidamente a todos los desarrolladores que comiencen a usar el modo estricto ahora. Hay suficientes navegadores que lo soportan que el modo estricto legítimamente ayudará a salvarnos de errores que ni siquiera sabíamos que estaban en su código.

Aparentemente, en la etapa inicial habrá errores que nunca hemos encontrado antes. Para obtener el máximo beneficio, debemos hacer las pruebas adecuadas después de cambiar al modo estricto para asegurarnos de haber capturado todo. Definitivamente no solo tiramos use strict en nuestro código y asumir que no hay errores. Entonces la rotación es que es hora de comenzar a usar esta función de lenguaje increíblemente útil para escribir un mejor código.

Por ejemplo,

var person = {
    name : 'xyz',
    position : 'abc',
    fullname : function () {  "use strict"; return this.name; }
};

JSLint es un depurador escrito por Douglas Crockford. Simplemente pegue su script y escaneará rápidamente en busca de problemas y errores detectables en su código.


122
2017-07-05 19:38



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 el Documentación de MDN para 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 futuras versiones de las normas ECMAScript introduzcan use como una palabra clave real; las citas se volverían obsoletas.
  • use strict solo se puede usar al comienzo de una secuencia de comandos o de una función, es decir, debe preceder a cualquier otra declaración (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.

los use strictLa directiva 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 un código use strict directiva. 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 use strict directiva. Código que se pasa a un eval() método se considera código estricto cuando eval() fue llamado desde un código estricto o contiene el use strict directiva en sí.

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 puedes usar el with-establecimiento 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 sistema global Object, entonces obtendrás un ReferenceError. En modo normal, el identificador se declara implícitamente como una variable global (como una propiedad del Object)
  • En modo estricto, la palabra clave this tiene el valor undefined en funciones que se invocaron como funciones (no como métodos). (En modo normal this siempre apunta a lo global Object) Esta diferencia se puede usar para probar si una implementación admite el modo estricto:
var hasStrictMode = (function() { "use strict"; return this===undefined }());
  • También cuando se invoca una función con call() o apply en modo estricto, entonces this es exactamente el valor del primer argumento de la call()o apply() invocación. (En modo normal null y undefined son reemplazados por el global Object y los valores, que no son objetos, se convierten en objetos).

  • En modo estricto obtendrá un TypeError, cuando intenta 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 cambio, se crea un nuevo alcance para eval() y las variables y funciones están dentro de ese alcance. Ese alcance se destruye después eval() termina 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 modo estricto obtendrá un SyntaxError cuando el delete al operador le sigue un identificador no calificado (una variable, función o parámetro de función). En modo normal, delete expresión no haría nada y se evalúa para false.
  • En modo estricto obtendrá un TypeError cuando intenta eliminar una propiedad no configurable. (En modo normal, el intento simplemente falla y el deleteexpresión se evalúa para 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, los literales octales no están permitidos (estos son literales que comienzan con 0x. (En modo normal, algunas implementaciones permiten literales octales).
  • En modo estricto, los identificadores eval y arguments son tratados 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 porque un TypeError en una función en modo estricto. Además, algunas propiedades de llamadas y argumentos de funciones en modo estricto causan TypeError cuando intentas leerlos

81
2018-05-15 06:58



Mis dos centavos:

Uno de los objetivos del modo estricto es permitir una depuración más rápida de los problemas. Ayuda a los desarrolladores lanzando excepciones cuando ocurren ciertas cosas incorrectas que pueden causar un comportamiento silencioso y extraño de su página web. El momento en que usamos use strict, el código arrojará errores que ayuden al desarrollador a solucionarlo con anticipación.

Pocas cosas importantes que he aprendido después de usar use strict :

Evita la declaración de variable global:

var tree1Data = { name: 'Banana Tree',age: 100,leafCount: 100000};

function Tree(typeOfTree) {
    var age;
    var leafCount;

    age = typeOfTree.age;
    leafCount = typeOfTree.leafCount;
    nameoftree = typeOfTree.name;
};

var tree1 = new Tree(tree1Data);
console.log(window);

Ahora, este código crea nameoftree en el ámbito global que se puede acceder utilizando window.nameoftree. Cuando implementamos use strict el código arrojaría error.

UnEdge ReferenceError: nameoftree no está definido

Muestra

Elimina with declaración:

with las declaraciones no se pueden minimizar utilizando herramientas como uglify-js. Ellos también son obsoleto y eliminado de futuras versiones de JavaScript.

Muestra

Previene duplicados:

Cuando tenemos propiedades duplicadas, arroja una excepción

Untaught SyntaxError: propiedad de datos duplicados en el objeto literal no   permitido en modo estricto

"use strict";
var tree1Data = {
    name: 'Banana Tree',
    age: 100,
    leafCount: 100000,
    name:'Banana Tree'
};

Hay algunos más, pero necesito obtener más conocimiento sobre eso.


73
2018-03-10 03:31



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 generalmente solo causarán un mal funcionamiento del script de alguna forma difícil de detectar en esos navegadores más antiguos).


54
2018-03-27 12:18