Modo estrito (use strict)
Esta aula explora o modo estrito do JavaScript, uma diretiva que altera a semântica do código para evitar erros silenciosos e melhorar a segurança. Você aprenderá o que muda, por que ativar e as principais diferenças de comportamento em relação ao modo não estrito.
O modo estrito ('use strict') é uma diretiva introduzida no ECMAScript 5 que permite optar por uma variante restrita do JavaScript. Ao ativá-lo, o interpretador aplica regras mais rígidas de sintaxe e execução, convertendo erros silenciosos em exceções explícitas. Essa diretiva é uma string literal simples no início de um script ou de uma função, e seu uso é fundamental para escrever código mais robusto, legível e menos propenso a bugs sutis.
Nesta aula, vamos mergulhar nas mudanças que o modo estrito impõe, entender os motivos para ativá-lo em seus projetos e explorar, com exemplos práticos, as principais diferenças de comportamento em relação ao modo normal. Ao final, você terá uma compreensão sólida de como usar o 'use strict' para melhorar a qualidade do seu código JavaScript.
O que muda
O modo estrito altera vários comportamentos da linguagem. Em primeiro lugar, ele impede a criação implícita de variáveis globais. No modo normal, atribuir um valor a uma variável não declarada cria uma propriedade global. No modo estrito, isso lança um erro ReferenceError. Essa mudança evita poluição do escopo global e erros de digitação que passam despercebidos.
Além disso, o modo estrito proíbe atribuições a propriedades não graváveis, getters somente leitura e propriedades não extensíveis. No modo normal, essas atribuições falham silenciosamente; no estrito, geram um TypeError. Também são proibidos parâmetros duplicados em funções, que no modo normal são permitidos (o último sobrescreve o primeiro). Outra mudança importante é que o valor de this em chamadas de função comuns não é mais o objeto global. No modo normal, this em uma função chamada sem contexto é o objeto global (no navegador, window); no estrito, é undefined. Isso evita acessos acidentais ao objeto global.
O modo estrito também elimina algumas construções consideradas problemáticas, como o uso da palavra-chave with, que é completamente proibida. Além disso, restringe o uso de literais octais (ex.: 010) que eram permitidos no modo normal. Por fim, ele torna a atribuição a identificadores não declarados (como eval ou arguments) mais restrita, e impede a exclusão de variáveis declaradas (com delete).
Veja um exemplo que ilustra a criação implícita de variável global:
// Modo normal
function normal() {
x = 10; // cria propriedade global x
}
normal();
console.log(x); // 10
// Modo estrito
function estrito() {
'use strict';
y = 20; // ReferenceError: y is not defined
}
estrito();Por que ativar
Ativar o modo estrito traz diversos benefícios para o desenvolvimento de software. O principal é a detecção precoce de erros: muitos erros que seriam silenciosos no modo normal se tornam exceções, facilitando a depuração. Isso é especialmente útil em projetos grandes, onde um erro sutil pode passar despercebido por muito tempo.
Além disso, o modo estrito melhora a performance em alguns casos, pois permite que o motor JavaScript faça otimizações que não são possíveis no modo normal. Por exemplo, a eliminação de with e a proibição de certas atribuições permitem que o compilador JIT assuma comportamentos mais previsíveis.
O modo estrito também promove boas práticas de programação, como declarar todas as variáveis com let, const ou var, e evitar o uso de recursos questionáveis. Isso torna o código mais legível e menos propenso a bugs. Em ambientes de equipe, adotar o modo estrito em todos os arquivos é uma política comum para padronizar o código.
Outro ponto é a segurança: o modo estrito reduz alguns vetores de ataque, como a manipulação do objeto global via this em funções. Como this é undefined em chamadas comuns, não há risco de vazar referências ao objeto global.
Exemplo de como ativar o modo estrito em um arquivo inteiro:
// Início do arquivo
'use strict';
function minhaFuncao() {
// código aqui
}Diferenças de comportamento
Vamos detalhar as principais diferenças de comportamento entre o modo normal e o modo estrito, com exemplos práticos para cada caso.
1. Atribuição a propriedades não graváveis
No modo normal, tentar modificar uma propriedade não gravável (definida com writable: false) falha silenciosamente. No modo estrito, lança um TypeError.
'use strict';
const obj = {};
Object.defineProperty(obj, 'x', { value: 42, writable: false });
obj.x = 100; // TypeError: Cannot assign to read only property 'x' of object2. Exclusão de propriedades não configuráveis
No modo normal, delete em uma propriedade não configurável retorna false sem erro. No estrito, lança TypeError.
'use strict';
const obj = {};
Object.defineProperty(obj, 'x', { value: 1, configurable: false });
delete obj.x; // TypeError: Cannot delete property 'x' of object3. Parâmetros duplicados
No modo normal, funções podem ter parâmetros com o mesmo nome; o último sobrescreve os anteriores. No modo estrito, isso é um erro de sintaxe.
function normal(a, a) {
return a;
}
console.log(normal(1, 2)); // 2
'use strict';
function estrito(a, a) { // SyntaxError: Duplicate parameter name not allowed in this context
return a;
}4. Valor de this em funções comuns
No modo normal, this em uma função chamada sem contexto é o objeto global. No estrito, é undefined.
function normal() {
console.log(this); // window (navegador)
}
normal();
'use strict';
function estrito() {
console.log(this); // undefined
}
estrito();5. Uso de eval
No modo normal, eval pode introduzir variáveis no escopo circundante. No estrito, eval cria um escopo próprio, não vazando variáveis.
function normal() {
eval('var x = 10;');
console.log(x); // 10
}
normal();
function estrito() {
'use strict';
eval('var y = 20;');
console.log(y); // ReferenceError: y is not defined
}
estrito();6. Palavra-chave with
O uso de with é completamente proibido no modo estrito, gerando erro de sintaxe.
// Modo normal
const obj = { x: 10 };
with (obj) {
console.log(x); // 10
}
// Modo estrito
'use strict';
with (obj) { // SyntaxError: Strict mode code may not include a with statement
console.log(x);
}7. Literais octais
No modo normal, literais numéricos com zero à esquerda são interpretados como octais (ex.: 010 é 8). No modo estrito, isso é um erro de sintaxe.
// Modo normal
var a = 010;
console.log(a); // 8
// Modo estrito
'use strict';
var b = 010; // SyntaxError: Octal literals are not allowed in strict mode.8. Exclusão de variáveis declaradas
No modo normal, delete em uma variável declarada retorna false sem erro. No estrito, lança SyntaxError.
'use strict';
var x = 1;
delete x; // SyntaxError: Delete of an unqualified identifier in strict mode.Boas práticas e observações finais
Recomenda-se ativar o modo estrito em todos os seus arquivos JavaScript, especialmente em projetos novos. Para scripts antigos, você pode adicionar a diretiva gradualmente, começando por arquivos que você está refatorando. Lembre-se de que a diretiva deve ser a primeira instrução no script ou na função; se houver qualquer código antes, ela será ignorada.
Uma dica importante: em módulos ES6, o modo estrito é ativado por padrão, portanto não é necessário adicionar a diretiva explicitamente. No entanto, em scripts clássicos, é essencial.
Além disso, sempre use let e const em vez de var para evitar problemas de escopo e reforçar a imutabilidade quando possível. O modo estrito complementa essas práticas, tornando o código mais seguro e previsível.
Por fim, lembre-se de que o modo estrito não é uma bala de prata: ele não impede todos os erros, mas reduz significativamente a chance de erros silenciosos. Combine-o com testes automatizados e boas ferramentas de lint para obter a máxima qualidade.
Referências
- MDN – Modo estrito
- MDN – var
- MDN – let
- MDN – const
- MDN – eval
- MDN – with
- ECMAScript Language Specification
Exercícios
Explique o que acontece quando você atribui um valor a uma variável não declarada dentro de uma função no modo estrito. Dê um exemplo.
✓ Resposta: No modo estrito, atribuir a uma variável não declarada lança umReferenceError. Por exemplo:function exemplo() { 'use strict'; x = 10; // ReferenceError: x is not defined }Qual é a diferença no valor de
thisem uma função chamada sem contexto no modo normal e no modo estrito? Ilustre com código.✓ Resposta: No modo normal,thisé o objeto global (window no navegador). No modo estrito, éundefined. Exemplo:function normal() { console.log(this); // window } function estrito() { 'use strict'; console.log(this); // undefined }Escreva um trecho de código que mostre a diferença no comportamento de
evalentre os dois modos.✓ Resposta: No modo normal,evalpode criar variáveis no escopo circundante; no estrito, não. Exemplo:function normal() { eval('var a = 1;'); console.log(a); // 1 } function estrito() { 'use strict'; eval('var b = 2;'); console.log(b); // ReferenceError }O que acontece se você tentar usar a palavra-chave
withno modo estrito? Cite o erro.✓ Resposta: O uso dewithé proibido no modo estrito e gera umSyntaxError. Exemplo:'use strict'; var obj = { x: 1 }; with (obj) { // SyntaxError: Strict mode code may not include a with statement console.log(x); }Liste três mudanças de comportamento que o modo estrito impõe e explique por que elas ajudam a evitar erros.
✓ Resposta: Três mudanças: (1) Proibição de variáveis globais implícitas, pois atribuir a uma variável não declarada gera erro, evitando poluição do escopo global; (2) Atribuições a propriedades somente leitura geram erro, evitando falhas silenciosas; (3)thisem funções comuns éundefined, evitando acesso acidental ao objeto global. Essas mudanças transformam erros silenciosos em exceções, facilitando a depuração e tornando o código mais seguro.