O que “use strict” faz em JavaScript e qual é o raciocínio por trás disso?


11 Answers

É um novo recurso do ECMAScript 5. John Resig escreveu um bom resumo dele.

É apenas uma string que você coloca em seus arquivos JavaScript (na parte superior do seu arquivo ou dentro de uma função) que se parece com isso:

"use strict";

Colocá-lo em seu código agora não deve causar problemas com os navegadores atuais, pois é apenas uma string. Isso pode causar problemas com seu código no futuro se seu código violar o pragma. Por exemplo, se você atualmente tem foo = "bar" sem definir foo primeiro, seu código começará a falhar ... o que é uma coisa boa na minha opinião.

Question

Recentemente, eu executei alguns dos meus códigos JavaScript através do JSLint de Crockford, e deu o seguinte erro:

Problema na linha 1 caractere 1: ausente "usar estrito" declaração.

Fazendo alguma pesquisa, percebi que algumas pessoas adicionam "use strict"; em seu código JavaScript. Depois que adicionei a declaração, o erro parou de aparecer. Infelizmente, o Google não revelou muito da história por trás dessa declaração de string. Certamente, deve ter algo a ver com a forma como o JavaScript é interpretado pelo navegador, mas não tenho ideia de qual seria o efeito.

Então, o que é "use strict"; tudo sobre o que isso implica, e ainda é relevante?

Algum dos navegadores atuais responde ao "use strict"; string ou é para uso futuro?




Ao adicionar "use strict"; , os casos a seguir lançarão um SyntaxError antes de o script ser executado:

  • Pavimentando o caminho para futuras versões do ECMAScript , usando uma das palavras-chave recém-reservadas (na previsão do ECMAScript 6 ): implements , interface , let , package , private , protected , public , static e yield .

  • Declarando função em blocos

    if(a<b){ function f(){} }
    
  • Sintaxe octal

    var n = 023;
    
  • this ponto para o objeto global.

     function f() {
          "use strict";
          this.a = 1;
     };
     f(); 
    
  • Declarando duas vezes o mesmo nome para um nome de propriedade em um literal de objeto

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

    Este não é mais o caso no ECMAScript 6 ( bug 1041128 ).

  • Declarando dois argumentos de função com a mesma função de nome

    f(a, b, b){}
    
  • Definindo um valor para uma variável não declarada

    function f(x){
       "use strict";
       var a = 12;
       b = a + x*35; // error!
    }
    f();
    
  • Usando delete em um nome de variável delete myVariable;

  • Usando eval ou arguments como variável ou nome do argumento da função

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

Fontes:




As principais razões pelas quais os desenvolvedores devem usar "use strict"são:

  1. Impede a declaração acidental de variáveis ​​globais . O uso "use strict()"garantirá que as variáveis ​​sejam declaradas varantes do uso. Por exemplo:

    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. Nota: A "use strict"diretiva é reconhecida apenas no início de um script ou de uma função.
  3. A string "arguments"não pode ser usada como uma variável:

    "use strict";
    var arguments = 3.14;    // This will cause an error
    
  4. Irá restringir o uso de palavras-chave como variáveis. Tentar usá-los causará erros.

Em suma, tornará seu código menos propenso a erros e, por sua vez, fará com que você escreva um bom código.

Para ler mais sobre isso, você pode se referir aqui .




Se você usa um navegador lançado no último ano, provavelmente ele é compatível com o modo JavaScript Strict. Apenas navegadores antigos antes do ECMAScript 5 se tornou o padrão atual, não o suportam.

As aspas ao redor do comando garantem que o código ainda funcionará em navegadores mais antigos (embora as coisas que geram um erro de sintaxe no modo estrito geralmente façam com que o script funcione mal em alguns desses navegadores mais antigos).




Se as pessoas estão preocupadas com o use strict , vale a pena conferir este artigo:

ECMAScript 5 'Modo estrito' suporte em navegadores. O que isto significa?
NovoGeek.com - o blog de Krishna

Ele fala sobre o suporte ao navegador, mas, mais importante, como lidar com isso de maneira 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.
*/



Note que use strictfoi introduzido no EcmaScript 5 e foi mantido desde então.

Abaixo estão as condições para acionar o modo estrito no ES6 e ES7 :

  • O código global é um código de modo estrito se começar com um Prólogo da Diretiva que contenha uma Diretiva de Uso Rígido (ver 14.1.1).
  • O código do módulo é sempre código de modo estrito.
  • Todas as partes de um ClassDeclaration ou um ClassExpression são código de modo estrito.
  • O código Eval é um código de modo estrito se começar com um Prólogo de Diretiva que contenha uma Diretriz Restrita de Uso ou se a chamada para eval for um eval direto (ver 12.3.4.1) contido no código de modo estrito.
  • O código de função é um código de modo estrito se o FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, MethodDefinition ou ArrowFunction associados estiver contido no código de modo estrito ou se o código que produz o valor do slot interno [[ECMAScriptCode]] da função começar com uma diretiva. que contém uma diretiva estrita de uso.
  • Código de função que é fornecido como os argumentos para os construtores internos de função e gerador é código de modo estrito se o último argumento é uma seqüência de caracteres que quando processada é um FunctionBody que começa com um prólogo de diretiva que contém uma diretiva de uso estrito.



Eu gostaria de oferecer uma resposta um pouco mais fundamentada, complementando as outras respostas. Eu estava esperando editar a resposta mais popular, mas falhei. Tentei torná-lo tão abrangente e completo quanto pude.

Você pode consultar a documentação do MDN para obter mais informações.

"use strict" uma diretiva introduzida no ECMAScript 5.

Diretivas são semelhantes às declarações, mas diferentes.

  • use strict não contém palavras-chave: A diretiva é uma declaração de expressão simples, que consiste em um literal de string especial (em aspas simples ou duplas). Mecanismos JavaScript, que não implementam ECMAScript 5, apenas veem uma declaração de expressão sem efeitos colaterais. Espera-se que futuras versões dos padrões ECMAScript introduzam o use como uma palavra-chave real; as cotações se tornariam obsoletas.
  • use strict pode ser usado somente no início de um script ou de uma função, ou seja, deve preceder todas as outras instruções (reais). Ele não precisa ser a primeira instrução em um script de função: ele pode ser precedido por outras expressões de instrução que consistem em literais de string (e implementações de JavaScript podem tratá-las como diretivas específicas de implementação). As instruções literais de string, que seguem uma primeira instrução real (em um script ou função) são instruções de expressão simples. Os intérpretes não devem interpretá-los como diretivas e eles não têm efeito.

A diretiva use strict indica que o código a seguir (em um script ou uma função) é um código estrito. O código no nível mais alto de um script (código que não está em uma função) é considerado código estrito quando o script contém uma diretiva use strict . O conteúdo de uma função é considerado código estrito quando a própria função é definida em um código estrito ou quando a função contém uma diretiva use strict . O código que é passado para um método eval() é considerado código estrito quando eval() foi chamado de um código estrito ou contém a própria diretiva use strict .

O modo estrito do ECMAScript 5 é um subconjunto restrito da linguagem JavaScript, que elimina os déficits relevantes da linguagem e apresenta uma verificação de erros mais rigorosa e maior segurança. A seguir lista as diferenças entre o modo estrito e o modo normal (dos quais os três primeiros são particularmente importantes):

  • Você não pode usar o comando -statement no modo estrito.
  • No modo estrito, todas as variáveis ​​devem ser declaradas: se você atribuir um valor a um identificador que não tenha sido declarado como variável, função, parâmetro da função, parâmetro da cláusula catch ou propriedade do Object global, você receberá um ReferenceError . No modo normal, o identificador é implicitamente declarado como uma variável global (como uma propriedade do Object global)
  • No modo estrito, a palavra this chave this tem o valor undefined em funções que foram chamadas como funções (não como métodos). (No modo normal, this sempre aponta para o Object global). Essa diferença pode ser usada para testar se uma implementação suporta o modo estrito:
var hasStrictMode = (function() { "use strict"; return this===undefined }());
  • Além disso, quando uma função é chamada com call() ou se apply no modo estrito, this é exatamente o valor do primeiro argumento da call() ou apply() . (No modo normal, null e undefined são substituídos pelo Object global e os valores, que não são objetos, são convertidos em objetos.)

  • No modo estrito, você receberá um TypeError , quando tentar atribuir a propriedades readonly ou definir novas propriedades para um objeto não extensível. (No modo normal, ambos simplesmente falham sem mensagem de erro.)

  • No modo estrito, ao passar o código para eval() , você não pode declarar ou definir variáveis ​​ou funções no escopo do chamador (como você pode fazer no modo normal). Em vez disso, um novo escopo é criado para eval() e as variáveis ​​e funções estão dentro desse escopo. Esse escopo é destruído depois que eval() finaliza a execução.
  • No modo estrito, o objeto-argumentos de uma função contém uma cópia estática dos valores, que são passados ​​para essa função. No modo normal, o objeto-argumentos tem um comportamento um tanto "mágico": os elementos da matriz e os parâmetros da função nomeados fazem referência ao mesmo valor.
  • No modo estrito, você receberá um SyntaxError quando o operador delete for seguido por um identificador não qualificado (um parâmetro de variável, função ou função). No modo normal, a expressão de delete não faria nada e é avaliada como false .
  • No modo estrito, você receberá um TypeError quando tentar excluir uma propriedade não configurável. (No modo normal, a tentativa simplesmente falha e a expressão de delete é avaliada como false ).
  • No modo estrito, é considerado um erro sintático quando você tenta definir várias propriedades com o mesmo nome para um literal de objeto. (No modo normal não há erro.)
  • No modo estrito, é considerado um erro sintático quando uma declaração de função possui vários parâmetros com o mesmo nome. (No modo normal não há erro.)
  • No modo estrito, literais octal não são permitidos (são literais que começam com 0x . (No modo normal, algumas implementações permitem literais octais).
  • No modo estrito, os identificadores eval e arguments são tratados como palavras-chave. Você não pode alterar seu valor, não pode atribuir um valor a eles e não pode usá-los como nomes para variáveis, funções, parâmetros de função ou identificadores de um bloco catch.
  • No modo estrito há mais restrições sobre as possibilidades de examinar a pilha de chamadas. arguments.caller e arguments.callee causam um TypeError em uma função no modo estrito. Além disso, algumas propriedades de caller e argumentos de funções no modo estrito causam um TypeError quando você tenta lê-las.



Há uma boa palestra de algumas pessoas que participaram do comitê ECMAScript: Alterações no JavaScript, Parte 1: ECMAScript 5 " sobre como o uso incremental do "use strict"switch permite que os implementadores de JavaScript limpem muitos dos recursos perigosos do JavaScript sem interromper todos os sites no mundo.

É claro que também fala sobre o que são muitas dessas irregularidades e como o ECMAScript 5 as conserta.




Normalmente, o script java não segue regras rígidas, aumentando assim as chances de erros. Após o uso "use strict", o código de script java deve seguir um conjunto estrito de regras, como em outras linguagens de programação, como o uso de terminadores, declaração antes da inicialização, etc.

Se "use strict"for usado, o código deve ser escrito seguindo um conjunto estrito de regras, diminuindo assim as chances de erros e ambiguidades.




Usando 'use strict'; não faz de repente seu código melhor.

O modo estrito de JavaScript é um recurso no ECMAScript 5 . Você pode ativar o modo estrito declarando isso no topo do seu script / função.

'use strict';

Quando um mecanismo JavaScript vê essa diretiva , ela começa a interpretar o código em um modo especial. Neste modo, os erros são gerados quando certas práticas de codificação que podem acabar sendo possíveis erros são detectadas (que é o raciocínio por trás do modo estrito).

Considere este exemplo:

var a = 365;
var b = 030;

Em sua obsessão de alinhar os literais numéricos, o desenvolvedor inadvertidamente inicializou a variável b com um literal octal. O modo não estrito interpretará isso como um literal numérico com valor 24 (na base 10). No entanto, o modo estrito emitirá um erro.

Para obter uma lista não exaustiva de especialidades no modo estrito, veja esta resposta .

Onde devo usar 'use strict'; ?

  • Na minha nova aplicação JavaScript: Absolutamente! O modo estrito pode ser usado como um denunciante quando você está fazendo algo estúpido com o seu código.

  • No meu código JavaScript existente : provavelmente não! Se o seu código JavaScript existente tiver instruções proibidas no modo estrito, o aplicativo simplesmente será interrompido. Se você quiser o modo estrito, você deve estar preparado para depurar e corrigir seu código existente. É por isso que usamos 'use strict'; não faz de repente seu código melhor .

Como eu uso o modo estrito?

  1. Inserir um 'use strict'; declaração no topo do seu script:

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

    Note que tudo no arquivo myscript.js será interpretado no modo estrito.

  2. Ou insira um 'use strict'; declaração no topo do seu corpo de função:

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

    Tudo no escopo léxico da função doSomething será interpretado no modo estrito. A palavra escopo léxico é importante aqui. Veja esta resposta para uma melhor explicação.

Quais coisas são proibidas no modo estrito?

Eu encontrei um bom artigo descrevendo várias coisas que são proibidas no modo estrito (note que esta não é uma lista exclusiva):

Escopo

Historicamente, o JavaScript ficou confuso sobre como as funções são definidas. Às vezes, eles parecem ter um escopo estatístico, mas alguns recursos fazem com que eles se comportem como se tivessem um escopo dinâmico. Isso é confuso, tornando os programas difíceis de ler e entender. Mal-entendido causa erros. Também é um problema de desempenho. O escopo estático permitiria que a vinculação de variáveis ​​acontecesse em tempo de compilação, mas o requisito para escopo dinâmico significa que a vinculação deve ser adiada para o tempo de execução, o que vem com uma penalidade de desempenho significativa.

O modo estrito requer que toda a ligação variável seja feita estaticamente. Isso significa que os recursos que anteriormente exigiam a vinculação dinâmica devem ser eliminados ou modificados. Especificamente, a instrução with é eliminada e a capacidade da função eval de adulterar o ambiente de seu chamador é severamente restrita.

Um dos benefícios do código estrito é que ferramentas como o YUI Compressor podem fazer um trabalho melhor ao processá-lo.

Variáveis ​​Globais Implícitas

JavaScript implicou variáveis ​​globais. Se você não declarar explicitamente uma variável, uma variável global será implicitamente declarada para você. Isso torna a programação mais fácil para iniciantes, porque eles podem negligenciar algumas de suas tarefas domésticas básicas. Mas isso torna o gerenciamento de programas maiores muito mais difícil e degrada significativamente a confiabilidade. Portanto, no modo estrito, as variáveis ​​globais implícitas não são mais criadas. Você deve declarar explicitamente todas as suas variáveis.

Vazamento Global

Há várias situações que podem fazer com que this seja vinculado ao objeto global. Por exemplo, se você esquecer de fornecer o new prefixo ao chamar uma função construtora, a do construtor será vinculada inesperadamente ao objeto global; assim, em vez de inicializar um novo objeto, ele estará silenciosamente interferindo nas variáveis ​​globais. Nessas situações, o modo estrito, em vez disso, ligará this a undefined , o que fará com que o construtor lance uma exceção, permitindo que o erro seja detectado muito mais cedo.

Falha ruidosa

O JavaScript sempre teve propriedades somente leitura, mas você não pode criá-las sozinho até que a função Object.createProperty do ES5 Object.createProperty essa capacidade. Se você tentou atribuir um valor a uma propriedade somente leitura, ele falharia silenciosamente. A atribuição não alteraria o valor da propriedade, mas seu programa continuaria como se tivesse. Esse é um risco de integridade que pode fazer com que os programas entrem em um estado inconsistente. No modo estrito, tentar alterar uma propriedade somente leitura lançará uma exceção.

Octal

A representação octal (ou base 8) dos números foi extremamente útil ao fazer programação em nível de máquina em máquinas cujo tamanho de palavra era um múltiplo de 3. Você precisava octal ao trabalhar com o mainframe CDC 6600, que tinha um tamanho de palavra de 60 bits. Se você pudesse ler octal, poderia ver uma palavra com 20 dígitos. Dois dígitos representaram o código op e um dígito identificou um dos 8 registros. Durante a transição lenta dos códigos de máquina para linguagens de alto nível, acreditava-se ser útil fornecer formulários octal nas linguagens de programação.

Em C, uma representação extremamente desafortunada de octalness foi selecionada: Leading zero. Portanto, em C, 0100 significa 64, não 100 e 08 é um erro, não 8. Ainda mais infelizmente, esse anacronismo foi copiado para quase todas as linguagens modernas, incluindo JavaScript, onde é usado apenas para criar erros. Não tem outro propósito. Portanto, no modo estrito, os formulários octal não são mais permitidos.

Etcetera

O pseudo array de argumentos torna-se um pouco mais parecido com um array no ES5. No modo estrito, ele perde suas propriedades de caller e caller . Isso torna possível passar seus arguments para código não confiável sem abrir mão de muito contexto confidencial. Além disso, a propriedade arguments de funções é eliminada.

No modo estrito, as chaves duplicadas em um literal de função produzirão um erro de sintaxe. Uma função não pode ter dois parâmetros com o mesmo nome. Uma função não pode ter uma variável com o mesmo nome de um dos seus parâmetros. Uma função não pode delete suas próprias variáveis. Uma tentativa de delete uma propriedade não configurável agora lança uma exceção. Valores primitivos não são implicitamente envolvidos.

Palavras reservadas para futuras versões do JavaScript

O ECMAScript 5 adiciona uma lista de palavras reservadas. Se você usá-los como variáveis ​​ou argumentos, o modo estrito causará um erro. As palavras reservadas são:

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

Leitura Adicional




Incluir use strictno início de todos os seus arquivos JavaScript sensíveis a partir deste ponto é uma pequena maneira de ser um programador JavaScript melhor e evitar que variáveis ​​aleatórias se tornem globais e as coisas mudem silenciosamente.




"use strict"; é o esforço do ECMA para tornar o JavaScript um pouco mais robusto. Ele traz em JS uma tentativa de torná-lo pelo menos um pouco "estrito" (outras linguagens implementam regras rígidas desde os anos 90). Na verdade, "força" os desenvolvedores de JavaScript a seguir algum tipo de práticas recomendadas de codificação. Ainda assim, o JavaScript é muito frágil. Não existem variáveis ​​tipadas, métodos tipados, etc. Recomendo fortemente que os desenvolvedores de JavaScript aprendam uma linguagem mais robusta, como Java ou ActionScript3, e implementem as mesmas práticas recomendadas em seu código JavaScript, ele funcionará melhor e será mais fácil depurar.




Related