o que é "modo estrito" e como é usado?

134

Eu estive examinando a referência JavaScript na Mozilla Developer Network, e me deparei com algo chamado "strict mode". Eu li e estou tendo problemas para entender o que faz. Alguém pode explicar brevemente (em geral) qual é o seu objetivo e como é útil?

nkcmr
fonte
2
Relacionados: stackoverflow.com/q/1335851/1461424
sampathsris

Respostas:

149

Seu principal objetivo é fazer mais verificações.

Basta adicionar "use strict";na parte superior do seu código, antes de qualquer outra coisa.

Por exemplo, blah = 33;é JavaScript válido. Isso significa que você cria uma variável completamente global blah.

Mas, no modo estrito, é um erro, porque você não usou a palavra-chave "var" para declarar a variável.

Na maioria das vezes, você não pretende criar variáveis ​​globais no meio de um escopo arbitrário; portanto, na maioria das vezes, isso blah = 33é escrito, é um erro e o programador realmente não quer que seja uma variável global. para escrever var blah = 33.

Da mesma forma, não permite muitas coisas tecnicamente válidas para fazer. NaN = "lol"não produz um erro. Também não altera o valor de NaN. usando estrito isso (e declarações estranhas semelhantes) produzem erros. A maioria das pessoas gosta disso porque não há motivo para escrever NaN = "lol", então provavelmente houve um erro de digitação.

Leia mais na página MDN no modo estrito

Simon Sarris
fonte
4
esta é uma duplicata exata da documentação no MDN
nkcmr 28/12/11
23
O que você não entende sobre sua utilidade então? O objetivo é ajudar o desenvolvimento, capturando coisas que são erros válidos, mas muito prováveis.
Simon Sarris
34

Um aspecto do modo estrito não já mencionados na resposta de Simon é que estritas conjuntos de modo thisa undefinedem funções invocado através da invocação da função.

Então coisas assim

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

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

causará um erro quando privateMethodfor chamado (já que você não pode adicionar uma propriedade a undefined), em vez de adicionar uma bpropriedade inutilmente ao objeto global.

Adam Rackis
fonte
4
sim precisa adicionar privateMethod.bind(this)();e ligar comnew jsbin.com
hlcs 15/05
A maioria das restrições importantes no modo estrito: docs.microsoft.com/en-us/scripting/javascript/advanced/...
Krishna Mohan
21

O modo estrito foi adicionado para que houvesse um subconjunto facilmente analisável estaticamente do EcmaScript, que seria um bom alvo para futuras versões da linguagem. O modo estrito também foi projetado na esperança de que os desenvolvedores que se limitam ao modo estrito cometessem menos erros e que os erros que eles cometem se manifestassem de maneiras mais óbvias.

A harmonia , que se tornará a próxima versão principal do EcmaScript, será construída sobre o ES5.

A harmonia se baseia no modo estrito do ES5 para evitar muitos modos.

Alguns outros experimentos de linguagem também dependem do modo estrito. O SES depende da capacidade de análise do modo estrito ES5.

Experiência de projeto SES (Secure ECMAScript)

Crie uma linguagem de programação de capacidade de objeto removendo ou reparando recursos no ES5 / Strict.

Deve haver uma tradução direta do SES para o ES5 / Strict.

O anexo C da norma explica as diferenças entre o modo estrito e o modo normal.

A restrição de modo estrito e exceções

  • Os identificadores "implementam", "interface", "let", "package", "private", "protected", "public", "static" e "yield" são classificados como tokens FutureReservedWord no código de modo estrito. (7.6.12 [?]).
  • Uma implementação em conformidade, ao processar código de modo estrito, não pode estender a sintaxe de NumericLiteral (7.8.3) para incluir OctalIntegerLiteral, conforme descrito em B.1.1.
  • Uma implementação em conformidade, ao processar o código de modo estrito (consulte 10.1.1), pode não estender a sintaxe do EscapeSequence para incluir OctalEscapeSequence, conforme descrito em B.1.2.
  • A atribuição a um identificador não declarado ou a uma referência não resolvível de outra forma não cria uma propriedade no objeto global. Quando uma atribuição simples ocorre dentro do código de modo estrito, o LeftHandSide não deve ser avaliado como uma referência não resolvível. Se isso ocorrer, uma exceção ReferenceError será lançada (8.7.2). O LeftHandSide também pode não ser uma referência a uma propriedade de dados com o valor do atributo {[[Writable]]: false}, a uma propriedade do acessador com o valor do atributo {[[Set]]: undefined}, ou a uma inexistente. propriedade de um objeto cuja propriedade interna [[Extensível]] possui o valor falso. Nesses casos, uma exceção TypeError é lançada (11.13.1).
  • O identificador eval ou argumentos podem não aparecer como LeftHandSideExpression de um operador de Atribuição (11.13) ou de um PostfixExpression (11.3) ou como a UnaryExpression operada por um operador Prefix Increment (11.4.4) ou Prefix Decrement (11.4.5) . Os objetos de argumentos para funções de modo estrito definem propriedades de acessador não configuráveis ​​denominadas "chamador" e "chamado", que lançam uma exceção TypeError no acesso (10.6).
  • Os objetos de argumentos para funções de modo estrito não compartilham dinamicamente seus valores de propriedade indexados à matriz com as ligações formais correspondentes correspondentes de suas funções. (10,6) Para funções de modo estrito, se um objeto de argumentos é criado, a ligação dos argumentos do identificador local ao objeto de argumentos é imutável e, portanto, pode não ser o destino de uma expressão de atribuição. (10,5)
  • É um SyntaxError se o código do modo estrito contiver um ObjectLiteral com mais de uma definição de qualquer propriedade de dados (11.1.5). É um SyntaxError se o identificador "eval" ou o identificador "argumentos" ocorrerem como o identificador em um PropertySetParameterList de um PropertyAssignment contido no código estrito ou se seu FunctionBody for código estrito (11.1.5).
  • O código de avaliação do modo estrito não pode instanciar variáveis ​​ou funções no ambiente variável do chamador a avaliar. Em vez disso, um novo ambiente variável é criado e esse ambiente é usado para instanciar a ligação de declaração para o código de avaliação (10.4.2).
  • Se isso for avaliado dentro do código de modo estrito, o valor this não será coagido a um objeto. Um valor nulo ou indefinido não é convertido no objeto global e os valores primitivos não são convertidos em objetos do wrapper. O valor this passado por meio de uma chamada de função (incluindo as chamadas feitas usando Function.prototype.apply e Function.prototype.call) não força o valor passado a um objeto (10.4.3, 11.1.1, 15.3.4.3, 15.3). 4.4)
  • Quando um operador de exclusão ocorre dentro do código de modo estrito, um SyntaxError é acionado se sua UnaryExpression for uma referência direta a uma variável, argumento de função ou nome da função (11.4.1).
  • Quando um operador de exclusão ocorre dentro do código de modo estrito, um TypeError é lançado se a propriedade a ser excluída tiver o atributo {[[Configurable]]: false} (11.4.1). É um SyntaxError se uma VariableDeclaration ou VariableDeclarationNoIn ocorrer dentro de um código estrito e seu Identificador for eval ou argumentos (12.2.1).
  • O código do modo estrito pode não incluir um WithStatement. A ocorrência de um WithStatement nesse contexto é um SyntaxError (12.10).
  • É um SyntaxError se um TryStatement com um Catch ocorrer dentro de um código estrito e o Identificador da produção Catch for eval ou argumentos (12.14.1)
  • É um SyntaxError se o identificador eval ou argumentos aparecerem em um FormalParameterList de um modo estrito FunctionDeclaration ou FunctionExpression (13.1)
  • Uma função de modo estrito pode não ter dois ou mais parâmetros formais com o mesmo nome. Uma tentativa de criar essa função usando um construtor FunctionDeclaration, FunctionExpression ou Function é um SyntaxError (13.1, 15.3.2).
  • Uma implementação não pode estender, além do definido nesta especificação, significados dentro de funções de modo estrito de propriedades denominadas chamador ou argumentos de instâncias de função. O código ECMAScript não pode criar ou modificar propriedades com esses nomes nos objetos de função que correspondem às funções de modo estrito (10.6, 13.2, 15.3.4.5.3).
  • É um SyntaxError usar dentro do código de modo estrito os identificadores eval ou argumentos como o Identificador de uma FunctionDeclaration ou FunctionExpression ou como um nome formal de parâmetro (13.1). Tentar definir dinamicamente uma função de modo estrito usando o construtor Function (15.3.2) lançará uma exceção SyntaxError.
Mike Samuel
fonte
6

O ECMAScript 5 introduziu o conceito de modo estrito .

Invocando o modo estrito no código

O modo estrito se aplica a scripts inteiros ou a funções individuais. Não se aplica à instrução de bloco entre chaves {}, tentar aplicá-la a esses contextos não faz nada.

Script inteiro:

Digamos que estamos criando o app.js, portanto, a adição do script de uso da primeira instrução aplicará um modo estrito para todo o código.

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

Modo estrito para a função:

Para invocar o modo estrito de uma função, coloque a declaração exata “use strict”; no início do corpo da função antes de qualquer outra instrução.

function yourFunc(){
 "use strict";

 // Your function code logic
}

O modo estrito incorpora várias alterações na semântica normal do Javascript. O primeiro modo estrito elimina algum erro silencioso do JavaScript, alterando-o para gerar erros.

Por exemplo: código usando o modo estrito

insira a descrição da imagem aqui

No exemplo de código acima, sem usar o modo estrito no código, ele não emitirá um erro. Como estamos acessando a variável xsem declará-la. Portanto, no modo estrito, acessar a variável não declarada gera um erro.

Agora vamos tentar acessar a variável x sem declará-la sem o modo estrito.

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

// Will not throw an error

Vantagem de usar o modo estrito:

  • Elimine erros silenciosos do JavaScript lançando um erro.
  • Corrige o erro que dificulta a otimização do mecanismo JavaScript.
  • Faça o código rodar mais rápido do que o código idêntico que não está no modo estrito
  • Proíbe alguma sintaxe que provavelmente será definida na versão futura do ECMAScript.
Nishant Kumar
fonte
5

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

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

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

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

Renganathan MG
fonte
1

ECMAScript5apresenta alguns novos objetos e propriedades e também os chamados "strict mode".

O modo estrito é um subconjunto do idioma que exclui recursos obsoletos. O modo estrito é ativado e não é obrigatório, o que significa que, se você deseja que seu código seja executado no modo estrito, declara sua intenção usando (uma vez por função ou uma vez para todo o programa) a seguinte string:

"use strict";
Vahid Hallaji
fonte
1

2017 e finalmente encontrei a documentação:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode

O modo estrito é uma maneira de ativar uma variante restrita do JavaScript. O modo estrito não é apenas um subconjunto: intencionalmente tem semântica diferente do código normal. Os navegadores que não suportam o modo estrito executarão código de modo estrito com um comportamento diferente dos navegadores que o fazem, portanto, não confie no modo estrito sem teste de recursos para suporte aos aspectos relevantes do modo estrito. O código do modo estrito e o código do modo não estrito podem coexistir, portanto, os scripts podem optar pelo modo estrito incrementalmente.


O modo estrito faz várias alterações na semântica normal do JavaScript. Primeiro, o modo estrito elimina alguns erros silenciosos do JavaScript, alterando-os para gerar erros. Segundo, o modo estrito corrige erros que dificultam a otimização dos mecanismos JavaScript: às vezes, o código do modo estrito pode ser executado mais rapidamente do que o código idêntico que não é o modo estrito. Terceiro, o modo estrito proíbe alguma sintaxe que provavelmente será definida em versões futuras do ECMAScript.

Tilak Maddy
fonte
0

Pergunta: A
seguir está o problema que encontrei, eu estava seguindo um tutorial e ele acabou tentando compilar o scssarquivo a seguir e tentando gerar código CSS a partir dele,

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

usando a seguinte gulpfile.jstarefa:

var gulp = require('gulp');
var sass = require('gulp-sass');

gulp.task('sass', function () {
    return gulp.src('app/scss/styles.scss')
        .pipe(sass())
        .pipe(gulp.dest('app/css'))
});

Portanto, o erro que estou recebendo é o seguinte:

~/htdocs/Learning/gulp1/node_modules/gulp-sass/index.js:66
    let sassMap;
    ^^^

SyntaxError: Block-scoped declarations (let, const, function, class) not yet supported outside strict mode
    at exports.runInThisContext (vm.js:53:16)
    at Module._compile (module.js:373:25)
// stacktrace here...

Solução:
Ele mostra o index.jsarquivo que está dentro do meu módulo gulp-sass (que está basicamente bloqueado e não deve ser editado). Mas se eu forçar com força e adicionar a "use_strict"parte superior desse index.jsarquivo, ele executará minha tarefa sem problemas.

Eu estava impotente, então continuo usando isso como solução! Mas depois de passar por algumas outras perguntas e respostas da SO , vi a seguinte resposta :

sudo npm install -g n
sudo n stable

e antes atualizei meus NodeJs (para Version10.x) e, em seguida, reconstruí o Gulp executando os seguintes comandos, conforme as instruções do Terminal:

npm rebuild node-sass --force

E está tudo bem. Então foi assim que foi resolvido. Eu desfiz as alterações que fiz no index.jsarquivo do módulo gulp. E agora funciona sem problemas.

Espero que esta resposta seja útil para alguém por aí!

Randika Vishman
fonte