O que "use strict" faz no JavaScript e qual é o raciocínio por trás disso?

7549

Recentemente, executei parte do meu código JavaScript no JSLint de Crockford e deu o seguinte erro:

Problema na linha 1, caractere 1: declaração "use strict" ausente.

Pesquisando, percebi que algumas pessoas adicionam "use strict";seu código JavaScript. Depois de adicionar a instrução, o erro parou de aparecer. Infelizmente, o Google não revelou grande parte da história por trás dessa declaração. Certamente, deve ter algo a ver com a maneira como o JavaScript é interpretado pelo navegador, mas não tenho idéia de qual seria o efeito.

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

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

Mark Rogers
fonte
5
As respostas aqui são antigas, mas estão erradas. A principal razão para o modo estrito não era para evitar erros de programação - que era para fazer JavaScript escopo léxico assim que poderia ser estaticamente analisável:]
Benjamin Gruenbaum
@BenjaminGruenbaum Usar "use strict";sozinho não torna o JS com escopo lexicamente. Declarar variáveis ​​com lete também constdeve ser usado.
Koorosh Pasokhi 14/01
Você está misturando entre o escopo do bloco e o lexical.
Benjamin Gruenbaum 15/01

Respostas:

4938

Este artigo sobre o Javascript Strict Mode pode lhe interessar: John Resig - ECMAScript 5 Strict Mode, JSON e mais

Para citar algumas partes interessantes:

O Modo Estrito é um novo recurso do ECMAScript 5 que permite colocar um programa ou uma função em um contexto operacional "estrito". Esse contexto estrito impede que determinadas ações sejam executadas e lança mais exceções.

E:

O modo estrito ajuda de duas maneiras:

  • Ele pega alguns erros comuns de codificação, lançando exceções.
  • Isso evita ou gera erros quando ações relativamente "inseguras" são executadas (como obter acesso ao objeto global).
  • Desativa recursos que são confusos ou mal pensados.

Observe também que você pode aplicar o "modo estrito" a todo o arquivo ... Ou pode usá-lo apenas para uma função específica (ainda citando o artigo de John Resig) :

// Non-strict code...

(function(){
  "use strict";

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

// Non-strict code... 

O que pode ser útil se você precisar misturar código antigo e novo ;-)

Então, suponho que seja um pouco como o que "use strict"você pode usar no Perl (daí o nome?) : Ajuda a cometer menos erros, detectando mais coisas que podem levar a quebras.

O modo estrito agora é suportado por todos os principais navegadores .

Dentro dos módulos ECMAScript nativos (com importe exportinstruções) e classes ES6 , o modo estrito está sempre ativado e não pode ser desativado.

Pascal MARTIN
fonte
100
Mudando o padrão depois de tantos anos? Tarde demais para isso: quebraria tantos sites / scripts / aplicativos existentes ... A única coisa possível é ajudar a melhorar as coisas para o futuro.
Pascal MARTIN
14
Tentei um pequeno trecho de código que seria inválido ao usar "use strict"no Firefox 3.6, Safari 5, Chrome 7 e Opera 10.6 (todos Mac). Sem erros, então eu acho que 'use strict' ainda não é suportado em nenhum navegador. Porém, não testei no IE9;) #
Husky Husky
11
Atualização rápida: o Firefox 4 tem suporte completo para o modo estrito e, até onde eu sei, nenhum outro navegador possui. O Safari e o Chrome têm suporte "parcial", mas eu realmente não sei o que isso significa.
Sasha Chedygov 8/02
29
Chrome 11 parece passar todos esses testes como faz IE10 ie.microsoft.com/testdrive/HTML5/TryStrict/Default.html#
gman
12
@ Julius - Isso não poderia ter sido implementado usando uma palavra-chave reservada, porque o código que tentava acionar o modo estrito seria interrompido nos navegadores antigos. Adicionar um literal de cadeia "aleatório" não quebra nada.
Nnnnnn
1245

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

É apenas uma string que você coloca nos arquivos JavaScript (na parte superior do arquivo ou dentro de uma função) que fica assim:

"use strict";

Colocá-lo no seu código agora não deve causar problemas nos navegadores atuais, pois é apenas uma sequência. Pode causar problemas no seu código no futuro, se violar o pragma. Por exemplo, se você tiver atualmente foo = "bar"sem definir fooprimeiro, seu código começará a falhar ... o que é uma coisa boa na minha opinião.

seth
fonte
329
Falhe rápido e falhe alto.
Niels Bom
31
Se você estiver escrevendo Javascript embutido em arquivos HTML, inicie cada novo bloco com <script>"use strict";. A bandeira se aplica somente ao bloco em que está incluída.
No5
7
É engraçado, isso resultou em seqüências de caracteres devem ter aspas simples. Então escreva 'use strict';vez
nilsi
1
então o que aconteceria com o conceito de elevação de javascript?
Sunil Sharma
1
@SunilSharma Se você tentar içar, mas falhar porque a variável não está definida, no momento a adicionará ao objeto global. Com "use strict";, falhará. Isso faz mais sentido, porque se ele for incluído no objeto global, significa que talvez não funcione na próxima vez em que você executar a função / executar outra coisa que redefina o bloco, pois estará no bloco mais alto (global).
Wizzwizz4
646

A instrução "use strict";instrui o navegador a usar o modo Estrito, que é um conjunto de recursos reduzido e mais seguro do JavaScript.

Lista de recursos (não exaustiva)

  1. Não permite variáveis ​​globais. (Captura vardeclarações ausentes e erros de digitação em nomes de variáveis)

  2. Atribuições com falha silenciosa geram erro no modo estrito (atribuindo NaN = 5;)

  3. Tentativas de excluir propriedades não excluídas lançarão ( delete Object.prototype)

  4. Requer que todos os nomes de propriedades em um literal de objeto sejam únicos ( var x = {x1: "1", x1: "2"})

  5. Os nomes dos parâmetros de função devem ser exclusivos ( function sum (x, x) {...})

  6. Proíbe a sintaxe octal ( var x = 023;alguns desenvolvedores assumem incorretamente que o zero anterior não faz nada para alterar o número.)

  7. Proíbe a withpalavra - chave

  8. eval no modo estrito não introduz novas variáveis

  9. Proíbe a exclusão de nomes simples ( delete x;)

  10. Proíbe a ligação ou atribuição de nomes evale argumentssob qualquer forma

  11. O modo estrito não aliasa propriedades do argumentsobjeto com os parâmetros formais. (ou seja, em function sum (a,b) { return arguments[0] + b;}Isso funciona porque arguments[0]está vinculado a ae assim por diante.)

  12. arguments.callee não é suportado

[Ref: Modo restrito , Mozilla Developer Network ]

gprasant
fonte
40
Lembrar: variáveis ​​globais são permitidas, apenas precisam ser explícitas (por exemplo window.foo = bar).
gcampbell
1
Exige que todos os nomes de propriedades em um literal objeto para ser único (var x = {x1: "1", x1: "2"}) é este válido
Arun Killu
4
Seu exemplo no 11 está faltando uma modificação de a (caso contrário, não faz sentido). I. e. soma da função (a, b) {a = 0; argumentos de retorno [0] + b; } alert (sum (1, 2)) retornará 3 com modo estrito e 2 sem modo estrito, devido ao alias.
David Gausmann 14/03/19
413

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

Suporte ao ECMAScript 5 'Strict mode' em navegadores. O que isto significa?
NovoGeek.com - blog de Krishna

Ele fala sobre o suporte ao navegador, mas o mais importante é como lidar com ele com segurança:

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.
*/
Jamie Hutber
fonte
116
Discordo. Eu acho que isso mostra por que é muito útil. Em essência, isso significa que este retorna a sua função e não awindow
Jamie Hutber
36
quando você quer a janela com thisa qual não pode mirar window?
21713 Jamie Hutber
14
Refere-se a si mesmo. thispertence à sua própria função e não a janela mundial
Jamie Hutber
26
No segundo, thisum é realmente undefined.
Broxzier 14/08/13
14
O ponto é que seu programa JS começará a falhar devido ao acesso a uma propriedade indefinida, em vez de fazer silenciosamente a coisa errada no objeto global. Facilita o rastreamento de erros sutis.
Stephen Chung
208

Uma palavra de cautela, todos os programadores exigentes: aplicar "use strict"ao código existente pode ser perigoso! Essa coisa não é um adesivo de cara feliz que você pode colocar no código para torná-lo 'melhor'. Com o"use strict" pragma, o navegador lançará repentinamente exceções em locais aleatórios que nunca foram lançados antes, porque naquele momento você está fazendo algo que o JavaScript padrão / solto permite, felizmente, mas abomina o JavaScript! Você pode ter violações de rigidez ocultas em chamadas raramente usadas no seu código, que só lançam uma exceção quando elas acabam sendo executadas - por exemplo, no ambiente de produção usado pelos clientes pagantes!

Se você quiser mergulhar, é uma boa ideia aplicar "use strict"testes de unidade abrangentes e uma tarefa de construção JSHint estritamente configurada que lhe dará alguma confiança de que não existe um canto escuro do seu módulo que exploda terrivelmente só porque você ativou o Modo estrito. Ou, ei, aqui está outra opção: simplesmente não adicione "use strict"nenhum código herdado, provavelmente é mais seguro assim, honestamente. DEFINITIVAMENTE, NÃO adicione "use strict"nenhum módulo que você não possua ou mantenha, como módulos de terceiros.

Eu acho que mesmo que seja um animal mortal enjaulado, "use strict"pode ser uma coisa boa, mas você precisa fazer o que é certo. O melhor momento para ser rigoroso é quando seu projeto é greenfield e você está começando do zero. Configure JSHint/JSLintcom todos os avisos e opções acionados o mais apertado que sua equipe possa suportar, obtenha um bom sistema de compilação / teste / asserção do mesmo tipo Grunt+Karma+Chai, e só então comece a marcar todos os seus novos módulos como "use strict". Esteja preparado para curar muitos erros e avisos negativos. Certifique-se de que todos entendam a gravidade configurando a compilação para FAIL se JSHint/JSLinthouver alguma violação.

Meu projeto não era um projeto greenfield quando adotei "use strict". Como resultado, meu IDE está cheio de marcas vermelhas porque não tenho"use strict" metade dos meus módulos, e o JSHint reclama disso. É um lembrete para mim sobre o que refatoração devo fazer no futuro. Meu objetivo é ser livre de marcas vermelhas devido a todas as minhas "use strict"declarações ausentes , mas isso é daqui a anos.

DWoldrich
fonte
24
POR QUE os desenvolvedores deste tópico são tão descuidados quanto ao "uso estrito"? Lança exceções no funcionamento de JavaScript , pelo amor de Deus! Apenas espalhe no código como açúcar em flocos de milho, não é? NÃO! RUIM! "use strict" deve ser usado com cautela, de preferência apenas no código que você controla que possui testes de unidade que são aprovados nos principais navegadores e que exercitam todos os caminhos de código. Você fez testes? Ok, "use strict" é bom para você, nocauteie-se.
DWoldrich
57
Sim. Obviamente, "use strict" pode quebrar o javascript aparentemente válido que não havia sido quebrado antes. Mas o código que não foi quebrado antes não é igual ao código estar correto e fazer o que deveria. Geralmente, fazer referência a variáveis ​​não declaradas sinaliza um erro de digitação etc. O uso estrito permite detectar esses tipos de erros e, esperançosamente, antes de enviar o código de produção.
Jostein Kjønigsen 9/03/15
5
... ou apenas aplicar "use strict" como parte de uma última passagem sobre seu código, corrigir todos os problemas óbvios, encolhendo os ombros, dizer "bom o suficiente", em seguida, levá-lo para a produção :)
Wolfie Inu
13
Pessoalmente, eu nunca / muito raramente adiciono "use strict"; ao código existente. Dito isto, eu vou quase sempre usá-lo quando estou escrevendo novo código a partir do zero
Martin
3
Se você já usa o JSLint, provavelmente consertou a maioria dos lugares em que "use strict" quebraria as coisas.
Jonathan Cast
179

O uso 'use strict';não melhora repentinamente o seu código.

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

'use strict';

Quando um mecanismo JavaScript vê essa diretiva , ele começa a interpretar o código em um modo especial. Nesse modo, erros são gerados quando determinadas 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 em alinhar os literais numéricos, o desenvolvedor inadvertidamente inicializou a variável bcom 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 gera um erro.

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


Onde devo usar 'use strict';?

  • No meu novo aplicativo JavaScript: Absolutamente! O modo estrito pode ser usado como denunciante quando você está fazendo algo estúpido com 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, esteja preparado para depurar e corrigir seu código existente. É por isso que o uso 'use strict';não melhora repentinamente o seu código .


Como uso o modo estrito?

  1. Insira uma 'use strict';declaração em cima do seu script:

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

    Observe que tudo no arquivo myscript.jsserá interpretado no modo estrito.

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

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

    Tudo no escopo lexical da função doSomethingserá interpretado no modo estrito. A palavra escopo lexical é importante aqui. Por exemplo, se o seu código estrito chama uma função de uma biblioteca que não é estrita , apenas seu código é executado no modo estrito, e não a função chamada. Veja esta resposta para uma melhor explicação.


Que coisas são proibidas no modo estrito?

Encontrei um bom artigo descrevendo várias coisas que são proibidas no modo estrito (observe que essa não é uma lista exclusiva):

Escopo

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

O modo estrito exige que toda a associação de variáveis ​​seja feita estaticamente. Isso significa que os recursos que anteriormente exigiam ligação dinâmica devem ser eliminados ou modificados. Especificamente, a instrução with é eliminada e a capacidade da função eval de violar o ambiente do 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 facilita a programação para iniciantes, porque eles podem negligenciar algumas de suas tarefas domésticas básicas. Mas torna o gerenciamento de programas maiores muito mais difícil e diminui 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 causar this a vinculação ao objeto global. Por exemplo, se você esquecer de fornecer o newprefixo ao chamar uma função de construtor, os construtores thisserão vinculados inesperadamente ao objeto global; portanto, em vez de inicializar um novo objeto, ele será violado silenciosamente com variáveis ​​globais. Nessas situações, o modo estrito será vinculado thisao undefined, o que fará com que o construtor lance uma exceção, permitindo que o erro seja detectado muito antes.

Falha ruidosa

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

Octal

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

Em C, foi selecionada uma representação extremamente lamentável da octalidade: Zero inicial. Então, em C, 0100significa 64, não 100, e 08é um erro, não 8. Ainda mais infelizmente, esse anacronismo foi copiado em quase todas as linguagens modernas, incluindo JavaScript, onde é usado apenas para criar erros. Não tem outro propósito. Portanto, no modo estrito, as formas octais não são mais permitidas.

Et cetera

Os argumentos pseudo-matriz se tornam um pouco mais parecidos com uma matriz no ES5. No modo estrito, perde suas propriedades calleee caller. Isso torna possível transmitir seu argumentscódigo não confiável sem abrir mão de muito contexto confidencial. Além disso, a argumentspropriedade das funções é eliminada.

No modo estrito, 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 que um de seus parâmetros. Uma função não pode ter deletesuas próprias variáveis. Uma tentativa de deleteuma propriedade não configurável agora lança uma exceção. Valores primitivos não são implicitamente agrupados.


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 gerará um erro. As palavras reservadas são:

implements, interface, let, package, private, protected, public, static, Eyield


Leitura adicional

sampathsris
fonte
2
é uma explicação muito boa. No entanto, tenho uma dúvida de que posso usar o modo "estrito" em conjunto com outras bibliotecas de scripts java, como o Angular js?
UVM
3
@ UV: A diretiva de modo estrito afeta apenas o escopo lexical. ou seja, apenas o arquivo / função que é declarado. Se você tiver outro arquivo / função que não possua a 'use strict'diretiva, eles serão executados no modo não estrito, mesmo quando chamados de uma função em execução no modo estrito. Veja este asnwer para uma explicação.
Sampathsris
Isso não é inteiramente correto. 'use strict' muda a maneira como o código é executado.
CyberEd
3
Na segunda olhada, você está certo. Eu pensei que você quisesse dizer que isso apenas gerava exceções, mas não mudou a maneira como o código funcionava (como mudar this). Agora vejo que você estava se referindo a chamar outras funções.
CyberEd
3
Existem alguns casos em que o octal é útil. A sintaxe C é horrível, mas eu gostaria de ter visto os idiomas adicionarem uma nova sintaxe octal que poderia permitir que a forma do zero à esquerda fosse preterida. Obviamente, para o Javascript ter suportado o formulário sem zero, era apenas bobo.
Supercat
138

Eu recomendo fortemente que todos os desenvolvedores comecem a usar o modo estrito agora. Existem navegadores suficientes compatíveis com esse modo estrito, que legitimamente nos ajudará a nos salvar de erros que nem sabíamos que estavam no seu código.

Aparentemente, no estágio inicial, haverá erros que nunca encontramos antes. Para obter todos os benefícios, precisamos fazer testes adequados depois de mudar para o modo estrito para garantir que capturamos tudo. Definitivamente, não apenas lançamos use strictnosso código e assumimos que não há erros. Portanto, a questão é que é hora de começar a usar esse recurso de linguagem incrivelmente útil para escrever um código melhor.

Por exemplo,

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

JSLint é um depurador escrito por Douglas Crockford. Basta colar o seu script e ele procurará rapidamente por problemas e erros perceptíveis no seu código.

Pank
fonte
6
@JamieHutber: Visite este link caniuse.com/use-strict AND kangax.github.io/es5-compat-table . Isso dará uma idéia exata para todos os navegadores.
Pank
95

Eu gostaria de oferecer uma resposta um pouco mais fundamentada, complementando as outras respostas. Eu esperava editar a resposta mais popular, mas falhei. Tentei torná-lo o mais abrangente e completo possível.

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

"use strict" uma diretiva introduzida no ECMAScript 5.

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

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

A use strictdiretiva indica que o código a seguir (em um script ou 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 use strictdiretiva. 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 use strictdiretiva. O código que é passado para um eval()método é considerado código estrito quando eval()foi chamado a partir de um código estrito ou contém a use strictprópria diretiva.

O modo estrito do ECMAScript 5 é um subconjunto restrito da linguagem JavaScript, que elimina déficits relevantes da linguagem e apresenta verificação de erros mais rigorosa e maior segurança. A seguir, são apresentadas 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 a withdeclaração no modo estrito.
  • No modo estrito, todas as variáveis ​​devem ser declaradas: se você atribuir um valor a um identificador que não foi declarado como variável, função, parâmetro de função, parâmetro de cláusula catch ou propriedade do global Object, você receberá a ReferenceError. No modo normal, o identificador é declarado implicitamente como uma variável global (como uma propriedade do global Object)
  • No modo estrito, a palavra this- chave tem o valor undefinedem funções que foram chamadas como funções (não como métodos). (No modo normal, thissempre aponta para o global Object). 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 applyno modo estrito, thisé exatamente o valor do primeiro argumento da call()ou apply()invocação. (No modo normal nulle undefinedsão substituídos pelo global Objecte os valores, que não são objetos, são convertidos em objetos.)

  • No modo estrito, você receberá a TypeErrorquando tentar atribuir propriedades somente leitura 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 é possível fazê-lo no modo normal). Em vez disso, um novo escopo é criado eval()e as variáveis ​​e funções estão dentro desse escopo. Esse escopo é destruído após o término da eval()execução.
  • No modo estrito, o objeto-argumento 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-argumento possui um comportamento um tanto "mágico": os elementos da matriz e os parâmetros da função nomeada referenciam o mesmo valor.
  • No modo estrito, você receberá a SyntaxErrorquando o deleteoperador for seguido por um identificador não qualificado (uma variável, função ou parâmetro de função). No modo normal, a deleteexpressão não faria nada e é avaliada comofalse .
  • No modo estrito, você receberá um TypeErrorquando tentar excluir uma propriedade não configurável. (No modo normal, a tentativa simplesmente falha e a deleteexpressão é avaliada como false).
  • No modo estrito, é considerado um erro sintático ao tentar 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 octais 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 evale argumentssã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 de captura.
  • No modo estrito, há mais restrições sobre as possibilidades de examinar a pilha de chamadas. arguments.callere arguments.calleecausar a TypeErrorem uma função no modo estrito. Além disso, algumas propriedades de chamadas e argumentos de funções no modo estrito causam um TypeErrorquando você tenta lê-las.
Ely
fonte
4
"No modo estrito, literais octais não são permitidos (estes são literais que começam com 0x ...)" literais octais começam com uma liderança 0.
Alex Gittemeier 11/08/16
83

Meus dois centavos:

Um dos objetivos do modo estrito é permitir a depuração mais rápida de problemas. Ajuda os desenvolvedores lançando exceção quando certas coisas erradas podem causar um comportamento silencioso e estranho da sua página da web. No momento em que usamos use strict, o código gera erros, o que ajuda o desenvolvedor a corrigi-lo com antecedência.

Poucas coisas importantes que aprendi depois de usar use strict:

Impede a declaração variável 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);

Agora, esse código cria nameoftreeno escopo global que pode ser acessado usando window.nameoftree. Quando implementamosuse strict o código lançaria um erro.

Não detectado ReferenceError: nameoftree não está definido

Sample

Elimina a withdeclaração:

withAs instruções não podem ser minificadas usando ferramentas como uglify-js . Eles também foram descontinuados e removidos de versões futuras do JavaScript.

Sample

Impede duplicatas:

Quando temos propriedade duplicada, ela lança uma exceção

SyntaxError não capturado: propriedade de dados duplicados no literal do objeto não permitida no modo estrito

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

Existem poucos, mas preciso obter mais conhecimento sobre isso.

Shubh
fonte
Com o ECMAScript 2015, nomes de propriedades duplicados são permitidos novamente! Consulte a documentação MDN .
philmcole 11/01
62

Se você usar um navegador lançado no ano passado, provavelmente será compatível com o modo Estrito JavaScript. Somente navegadores antigos anteriores ao ECMAScript 5 se tornaram o padrão atual não o suportam.

As aspas ao redor do comando garantem que o código ainda funcione em navegadores mais antigos (embora as coisas que geram um erro de sintaxe no modo estrito geralmente causem mau funcionamento do script de alguma maneira difícil de detectar nesses navegadores mais antigos).

Stephen
fonte
12
Então o que isso faz?
Anish Gupta
7
... isso descreve em parte a compatibilidade, mas não o que realmente faz.
22712
58

Ao adicionar "use strict";, os seguintes casos lançam um SyntaxError antes da execução do script:

  • Pavimentando o caminho para futuras versões ECMAScript , usando uma das palavras-chave recém-reservados (em previsão para 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 aponte para o objeto global.

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

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

    Esse não é mais o caso do ECMAScript 6 ( bug 1041128 ).

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

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

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

  • Usando evalou argumentscomo nome de argumento de variável ou função

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

Fontes:

zangw
fonte
Com o ECMAScript 2015, nomes de propriedades duplicados são permitidos novamente! Consulte a documentação MDN .
philmcole 11/01
53

O modo estrito faz várias alterações na semântica normal do JavaScript:

  • elimina alguns erros silenciosos do JavaScript, alterando-os para gerar erros.

  • corrige erros que dificultam a otimização dos mecanismos JavaScript.

  • proíbe alguma sintaxe que provavelmente será definida em versões futuras do ECMAScript.

para obter mais informações, visite Strict Mode- Javascript

Renganathan MG
fonte
52

"Use estrito"; é um seguro que o programador não usará as propriedades frouxas ou ruins do JavaScript. É um guia, assim como uma régua o ajudará a fazer linhas retas. "Use Strict" ajudará você a "Codificação direta".

Aqueles que preferem não usar réguas para fazer suas linhas retas geralmente acabam nessas páginas pedindo para que outros depurem seu código.

Acredite em mim. A sobrecarga é insignificante em comparação com o código mal projetado. Doug Crockford, que é desenvolvedor sênior de JavaScript há vários anos, tem um post muito interessante aqui . Pessoalmente, gosto de voltar ao site o tempo todo para garantir que não esqueço minhas boas práticas.

A prática moderna de JavaScript deve sempre evocar o "Use Strict"; pragma. O único motivo pelo qual o Grupo ECMA tornou opcional o modo "Estrito" é permitir que codificadores menos experientes tenham acesso ao JavaScript e, então, tempo para se adaptarem às práticas de codificação novas e mais seguras.

user2436758
fonte
66
O motivo pelo qual o modo estrito é opcional não tem nada a ver com o que você declarou. O verdadeiro motivo é não quebrar o código existente que pode não estar em conformidade .
Dexygen
17
De fato, os codificadores menos experientes devem ser os primeiros a permitir o "uso estrito";
Antti Haapala
46

A inclusão use strictno início de todos os 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.

Placeholder
fonte
42

Citando w3schools :

A diretiva "uso estrito"

A diretiva "use strict" é nova no JavaScript 1.8.5 (ECMAScript versão 5).

Não é uma declaração, mas uma expressão literal, ignorada pelas versões anteriores do JavaScript.

O objetivo de "usar estrito" é indicar que o código deve ser executado no "modo estrito".

Com o modo estrito, você não pode, por exemplo, usar variáveis ​​não declaradas.

Por que modo estrito?

O modo estrito facilita a gravação de JavaScript "seguro".

O modo estrito altera a "sintaxe incorreta" anteriormente aceita em erros reais.

Como exemplo, no JavaScript normal, digitar incorretamente um nome de variável cria uma nova variável global. No modo estrito, isso gerará um erro, tornando impossível criar acidentalmente uma variável global.

Em JavaScript normal, um desenvolvedor não receberá nenhum feedback de erro ao atribuir valores a propriedades não graváveis.

No modo estrito, qualquer atribuição a uma propriedade não gravável, uma propriedade somente getter, uma propriedade inexistente, uma variável inexistente ou um objeto inexistente gerará um erro.

Consulte http://www.w3schools.com/js/js_strict.asp para saber mais

Heich-B
fonte
37

"use strict"faz com que o código JavaScript seja executado no modo estrito , o que basicamente significa que tudo precisa ser definido antes do uso. O principal motivo para usar o modo estrito é evitar usos globais acidentais de métodos indefinidos.

Também no modo estrito, as coisas correm mais rápido, alguns avisos ou avisos silenciosos geram erros fatais; é melhor sempre usá-lo para criar um código mais limpo.

"use strict"é amplamente necessário para ser usado no ECMA5, no ECMA6 faz parte do JavaScript por padrão , portanto, não precisa ser adicionado se você estiver usando o ES6.

Veja estas instruções e exemplos do MDN:

A diretiva
"use strict" A diretiva "use strict" é nova no JavaScript 1.8.5 (ECMAScript versão 5). Não é uma declaração, mas uma expressão literal, ignorada pelas versões anteriores do JavaScript. O objetivo de "usar estrito" é indicar que o código deve ser executado no "modo estrito". Com o modo estrito, você não pode, por exemplo, usar variáveis ​​não declaradas.

Exemplos de uso de "use strict":
Modo estrito para funções: Da mesma forma, para invocar o modo estrito para uma função, coloque a instrução exata "use strict"; (ou 'use strict';) no corpo da função antes de qualquer outra declaração.

1) modo estrito em funções

 function strict() {
     // Function-level strict mode syntax
     'use strict';
     function nested() { return 'And so am I!'; }
     return "Hi!  I'm a strict mode function!  " + nested();
 }
 function notStrict() { return "I'm not strict."; }

 console.log(strict(), notStrict());

2) modo estrito de script inteiro

'use strict';
var v = "Hi! I'm a strict mode script!";
console.log(v);

3) Atribuição a um sistema global não gravável

'use strict';

// Assignment to a non-writable global
var undefined = 5; // throws a TypeError
var Infinity = 5; // throws a TypeError

// Assignment to a non-writable property
var obj1 = {};
Object.defineProperty(obj1, 'x', { value: 42, writable: false });
obj1.x = 9; // throws a TypeError

// Assignment to a getter-only property
var obj2 = { get x() { return 17; } };
obj2.x = 5; // throws a TypeError

// Assignment to a new property on a non-extensible object.
var fixed = {};
Object.preventExtensions(fixed);
fixed.newProp = 'ohai'; // throws a TypeError

Você pode ler mais sobre MDN .

Alireza
fonte
31

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

Obviamente, ele também fala sobre o que muitas dessas falhas são (foram) e como o ECMAScript 5 as corrige.

FutureNerd
fonte
27

Pequenos exemplos para comparar:

Modo não estrito:

for (i of [1,2,3]) console.log(i)
    
// output:
// 1
// 2
// 3

Modo estrito:

'use strict';
for (i of [1,2,3]) console.log(i)

// output:
// Uncaught ReferenceError: i is not defined

Modo não estrito:

String.prototype.test = function () {
  console.log(typeof this === 'string');
};

'a'.test();

// output
// false

String.prototype.test = function () {
  'use strict';
  
  console.log(typeof this === 'string');
};

'a'.test();

// output
// true

Bronzeado
fonte
2
Observe que o código acima adicionará a variável i ao escopo global (geralmente essa não é uma prática recomendada e o modo estrito ajuda a evitar isso).
22617 Michael
1
Alguém pode explicar o segundo exemplo? Eu não entendo. Não deveria this === 'a'nos dois exemplos?
MaximeW #
19

Observe 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 de diretiva que contém uma diretiva de uso estrito (consulte 14.1.1).
  • O código do módulo é sempre código de modo estrito.
  • Todas as partes de um ClassDeclaration ou ClassExpression são código de modo estrito.
  • O código de avaliação é um código de modo estrito se começar com um prólogo de diretiva que contenha uma diretiva de uso estrito ou se a chamada para avaliação for uma avaliação direta (consulte 12.3.4.1) contida no código de modo estrito.
  • O código da função é um código de modo estrito se o FunctionDeclaration, FunctionExpression, GeneratorDeclaration, GeneratorExpression, MethodDefinition ou ArrowFunction 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 um Prólogo de Diretiva que contém uma diretiva estrita de uso.
  • O código de função que é fornecido como argumento para os construtores Function e Generator internos é um código de modo estrito se o último argumento for uma String que, quando processada, é um FunctionBody que começa com um prólogo de diretiva que contém uma diretiva de uso estrito.
Oriol
fonte
14

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

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

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

Para ler mais sobre isso, você pode consultar aqui .

Pritam Banerjee
fonte
12

"use strict"; é o esforço da ECMA para tornar o JavaScript um pouco mais robusto. Ele traz ao JS uma tentativa de torná-lo pelo menos um pouco "estrito" (outros idiomas implementam regras estritas desde os anos 90). Na verdade, "força" os desenvolvedores JavaScript a seguir algum tipo de prática recomendada de codificação. Ainda assim, o JavaScript é muito frágil. Não existem variáveis ​​digitadas, métodos digitados, etc. Recomendo vivamente aos desenvolvedores JavaScript que aprendam uma linguagem mais robusta, como Java ou ActionScript3, e que implementem as mesmas práticas recomendadas no código JavaScript, que funcionará melhor e será mais fácil. depurar.

PippoApps.com
fonte
12

O modo "estrito" do JavaScript foi introduzido no ECMAScript 5.

(function() {
  "use strict";
  your code...
})();

Escrever "use strict";na parte superior do seu arquivo JS ativa a verificação rigorosa de sintaxe. Ele realiza as seguintes tarefas para nós:

  1. mostra um erro se você tentar atribuir a uma variável não declarada

  2. impede que você substitua as principais bibliotecas do sistema JS

  3. proíbe alguns recursos de idioma inseguros ou propensos a erros

use stricttambém funciona dentro de funções individuais. É sempre uma prática melhor incluir use strictno seu código.

Problema de compatibilidade do navegador: as diretivas "use" devem ser compatíveis com versões anteriores. Os navegadores que não os suportam verão apenas uma literal de sequência que não é mais referenciada. Então, eles vão passar por cima e seguir em frente.

Rabin Pantha
fonte
12

use stricté uma maneira de tornar seu código mais seguro, porque você não pode usar recursos perigosos que podem não funcionar como o esperado. E, como foi escrito antes, torna o código mais rigoroso.

Просто программист
fonte
11

Use Strict é usado para mostrar erros comuns e repetidos para que sejam tratados de maneira diferente e altera a maneira como o script java é executado, tais alterações são:

  • Impede globals acidentais

  • Sem duplicatas

  • Elimina com

  • Elimina essa coerção

  • Avaliação mais segura ()

  • Erros para imutáveis

você também pode ler este artigo para obter detalhes

Wesam
fonte
11

Normalmente, o JavaScript não segue regras rígidas, aumentando assim as chances de erros. Após o uso "use strict", o código JavaScript deve seguir um conjunto estrito de regras, como em outras linguagens de programação, como 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 as chances de erros e ambiguidades.

Bikash Chapagain
fonte
7

"use strict"; Define que o código JavaScript deve ser executado no "modo estrito".

  • A diretiva "use strict" era nova no ECMAScript versão 5.
  • Não é uma declaração, mas uma expressão literal, ignorada pelas versões anteriores do JavaScript.
  • O objetivo de "usar estrito" é indicar que o código deve ser executado no "modo estrito".
  • Com o modo estrito, você não pode, por exemplo, usar variáveis ​​não declaradas.

Todos os navegadores modernos suportam "use strict", exceto o Internet Explorer 9 e versões inferiores .

Desvantagem

Se um desenvolvedor usou uma biblioteca que estava no modo estrito, mas o desenvolvedor estava acostumado a trabalhar no modo normal, ele pode chamar algumas ações na biblioteca que não funcionariam conforme o esperado.

Pior ainda, como o desenvolvedor está no modo normal, ele não tem as vantagens de gerar erros extras; portanto, o erro pode falhar silenciosamente.

Além disso, conforme listado acima, o modo estrito impede que você faça certas coisas.

As pessoas geralmente pensam que você não deve usar essas coisas em primeiro lugar, mas alguns desenvolvedores não gostam da restrição e querem usar todos os recursos da linguagem.

Ashish
fonte
4

O modo estrito pode impedir vazamentos de memória.

Verifique a função abaixo, escrita no modo não estrito:

function getname(){
    name = "Stack Overflow"; // Not using var keyword
    return name;
}
getname();
console.log(name); // Stack Overflow

Nesta função, estamos usando uma variável chamada name dentro da função. Internamente, o compilador primeiro verificará se há alguma variável declarada com esse nome específico naquele escopo de função específico. Como o compilador entendeu que não existe essa variável, ele fará o check-in no escopo externo. No nosso caso, é o escopo global. Novamente, o compilador entendeu que também não há variável declarada no espaço global com esse nome, portanto, ele cria uma variável para nós no espaço global. Conceitualmente, essa variável será criada no escopo global e estará disponível em todo o aplicativo.

Outro cenário é que, digamos, a variável seja declarada em uma função filho. Nesse caso, o compilador verifica a validade dessa variável no escopo externo, ou seja, a função pai. Só então ele fará o check-in no espaço global e criará uma variável para nós lá. Isso significa que verificações adicionais precisam ser feitas. Isso afetará o desempenho do aplicativo.


Agora vamos escrever a mesma função no modo estrito.

"use strict"
function getname(){
    name = "Stack Overflow"; // Not using var keyword
    return name;
}
getname();
console.log(name); 

Obteremos o seguinte erro.

Uncaught ReferenceError: name is not defined
at getname (<anonymous>:3:15)
at <anonymous>:6:5

Aqui, o compilador lança o erro de referência. No modo estrito, o compilador não nos permite usar a variável sem declará-la. Portanto, vazamentos de memória podem ser evitados. Além disso, podemos escrever um código mais otimizado.

Jerin K Alexander
fonte