O JavaScript continua sendo uma das linguagens de programação mais utilizadas na web, alimentando tudo, desde formas interativas simples até aplicações complexas de uma única página. À medida que os projetos crescem em tamanho e os membros da equipe aumentam, a necessidade de código confiável e previsível torna-se primordial. É aí que o modo rígido do JavaScript – uma característica introduzida no ECMAScript 5 – entra em jogo. O modo rígido permite que os desenvolvedores optem em uma variante restrita da linguagem, ajudando a capturar erros comuns, prevenir ações perigosas e, em última análise, produzir um código mais seguro e mantenível. Ao reforçar a análise e o manuseio de erros mais rigorosos, o modo rígido transforma falhas anteriormente silenciosas em exceções explícitas, tornando a depuração mais fácil e encorajando melhores hábitos de codificação. Neste guia abrangente, vamos explorar o modo rígido, como habilitá-lo, seus muitos benefícios e exemplos práticos para ilustrar seu impacto.

O que é o modo estrito?

O modo rígido é uma forma de escolher um subconjunto mais disciplinado do JavaScript. Quando habilitado, o motor JavaScript executa o código sob um conjunto de restrições que eliminam algumas das funcionalidades mais propensas a erros. A ideia por trás do modo estrito é fornecer aos desenvolvedores um feedback mais precoce sobre problemas potenciais. Por exemplo, no modo não restrito (muitas vezes chamado de "modo lento"), atribuindo um valor a uma variável não declarada silenciosamente cria uma variável global. No modo estrito, isto lança um [[FLT: 0]]. Da mesma forma, o modo estrito permite o uso de certas construções desprecadadas ou problemáticas, tais como a instrução [[FLT: 1]] e literais numéricos octais. O objetivo é tornar o JavaScript mais confiável, seguro e consistente, especialmente em grandes bases de código.

O ECMAScript 5 introduziu o modo estrito em 2009 como uma forma de evoluir a linguagem sem quebrar a compatibilidade com o backward. Os desenvolvedores poderiam optar pelo novo comportamento mais rigoroso simplesmente adicionando no topo de um script ou função. Desde então, o modo rígido tornou-se uma prática recomendada em muitos guias de estilo e é automaticamente aplicado em construções de JavaScript modernas como módulos ES (importação/exportação) e corpos de classe. Compreender como o modo rígido opera é essencial para qualquer desenvolvedor profissional de JavaScript.

Como ativar o modo rígido

A ativação do modo estrito é simples: você insere a string literal (ou ]) no início de um script ou função. Esta diretiva não é uma instrução, mas um pragma que diz ao motor para analisar o código subsequente em modo estrito. Ele pode ser aplicado em dois escopos: globalmente (para um script inteiro) ou localmente (para uma única função). Além disso, os módulos e classes ES estão automaticamente em modo estrito, de modo que não é necessária nenhuma diretiva explícita.

Modo Estrito de Nível de Programa

Para ativar o modo rígido para um arquivo JavaScript inteiro ou em linha bloco, coloque como a primeira linha do script (antes de quaisquer outras instruções). Por exemplo:

// script.js
'use strict';

var x = 10;
console.log(x); // works normally

// Attempting to use undeclared variables throws an error
y = 20; // ReferenceError: y is not defined

Quando aplicado globalmente, o modo estrito afeta todo o código nesse arquivo de script. Se você concatenar vários scripts, somente aqueles que começam com serão executados em modo estrito. É importante notar que um script de modo estrito não pode misturar com código não- restrito no mesmo arquivo, a menos que você use o escopo de nível de função.

Modo Estrito de Nível de Função

Você também pode ativar o modo rígido dentro de uma função específica, deixando o resto do script em modo desleixado. Isto é útil quando gradualmente migrando uma base de código ou quando você deseja verificar rigorosamente apenas para certas funções. Coloque no topo do corpo da função, antes de quaisquer outras instruções:

function strictFunction() {
 'use strict';
 // Inside this function, strict mode applies
 var a = 1;
 b = 2; // ReferenceError: b is not defined
}

function sloppyFunction() {
 // Outside strictFunction, sloppy mode still applies
 c = 3; // creates global variable c
}

O modo rígido de função aplica-se apenas ao próprio código da função, não a quaisquer funções aninhadas (a menos que também declarem ). No entanto, na prática, é comum definir o modo estrito no nível de arquivo para consistência.

Módulos e Classes

Com o advento do ES6 (ES2015), o JavaScript introduziu módulos e classes. Ambos estão automaticamente em modo estrito por padrão. Portanto, se você escrever seu código usando sintaxe / ou definir uma , você não precisa adicionar —o modo restrito é aplicado automaticamente. Por exemplo:

// module.js (no 'use strict' needed)
export function add(a, b) {
 // strict mode is active here
 return a + b;
}

// class definition (strict mode active)
class MyClass {
 constructor(value) {
 this.value = value;
 }
}

Esta aplicação automática torna o código em módulos e classes inerentemente mais seguro e mais fácil de raciocinar.

Principais benefícios de usar o modo rígido

O modo rígido oferece uma série de benefícios que melhora diretamente a qualidade do código, segurança e experiência do desenvolvedor. Vamos examinar cada benefício em detalhes.

Previne Variáveis Acidentais Globais

No modo não restrito, atribuir um valor a uma variável não declarada cria automaticamente uma propriedade no objeto global (] nos navegadores, em Node.js). Isto pode acontecer facilmente devido a erros tipográficos ou declarações esquecidas, poluindo o espaço de nomes global e causando erros sutis. O modo rígido torna isso impossível ao lançar um . Por exemplo:

// Non-strict: silently creates global variable
function setup() {
 developer = "Alice"; // accidentally global
}

// Strict: throws ReferenceError
function setup() {
 'use strict';
 developer = "Alice"; // ReferenceError: developer is not defined
}

Esta aplicação obriga os desenvolvedores a declarar explicitamente variáveis com , , ou , reduzindo bugs relacionados ao escopo.

Elimina erros silenciosos

O JavaScript é muitas vezes perdoador quando as operações falham silenciosamente. Por exemplo, atribuir a uma propriedade só de leitura (como [[FLT: 24]]] ou um objeto congelado) simplesmente não faz nada em modo desleixado. Em modo estrito, tais atribuições lançam um [[FLT: 25]]. Da mesma forma, tenta apagar propriedades indeléveis (por exemplo, [FLT: 26]]) lançam um erro em vez de retornar silenciosamente [[FLT: 27]]. Isto torna a depuração muito mais fácil porque o desenvolvedor recebe feedback imediato.

// Non-strict: assignment silently fails
var obj = Object.freeze({name: "Bob"});
obj.name = "Charlie"; // silently ignored

// Strict: TypeError thrown
'use strict';
var obj = Object.freeze({name: "Bob"});
obj.name = "Charlie"; // TypeError: Cannot assign to read-only property 'name'

Previne nomes de parâmetros duplicados

No modo não- restrito, as funções podem ter nomes de parâmetros duplicados, o que pode levar a um comportamento confuso (a última duplicata substitui as anteriores). O modo rígido proíbe isto, lançando um no tempo de análise. Por exemplo:

// Non-strict: allowed
function sum(a, a, c) {
 return a + a + c; // a equals the second argument passed
}

// Strict: SyntaxError
'use strict';
function sum(a, a, c) { // SyntaxError: Duplicate parameter name not allowed in strict mode
 return a + a + c;
}

Esta restrição ajuda a evitar a sobreposição acidental de parâmetros, tornando as assinaturas de função mais claras e menos propensas a erros.

Restringe a declaração

A instrução tem sido considerada prejudicial porque cria ambiguidade sobre resolução variável e degrada o desempenho. Modo rígido completamente não permite a instrução , lançando uma ] no momento da compilação. Esta remoção incentiva os desenvolvedores a usar padrões mais previsíveis, como destruturação ou acesso explícito à propriedade.

Torna mais seguro

No modo não restrito, pode introduzir novas variáveis no escopo circundante, levando a efeitos colaterais imprevisíveis. O modo rígido muda o comportamento de para que ele crie variáveis apenas dentro do próprio código de avaliação – eles não vazam no contexto envolvente. Isso torna o código mais fácil de raciocinar e evita poluição acidental.

// Non-strict: eval creates variable in outer scope
var x = 1;
eval("var x = 2;");
console.log(x); // 2

// Strict: eval has its own scope
'use strict';
var x = 1;
eval("var x = 2;");
console.log(x); // 1

Proibições dos literais numéricos octais

Historicamente, o JavaScript interpretou números com um zero inicial (por exemplo, ]) como octal (base 8). Este comportamento frequentemente causou confusão e erros, especialmente quando lida com strings como "010" sendo analisado como números. O modo rígido proíbe literais numéricos octais (exceto para o prefixo ES6+ ) e lança um . Isto elimina uma classe inteira de erros sutis.

// Non-strict: 010 means octal 8
console.log(010); // 8

// Strict: SyntaxError
'use strict';
console.log(010); // SyntaxError: Octal literals are not allowed in strict mode

Não permite excluir variáveis simples

No modo não restrito, você pode tentar excluir variáveis ou declarações de função, mas a operação silenciosamente falha (] retorna ). O modo rígido lança um ] se você tentar excluir uma variável, função ou parâmetro de função simples. Isto impede tentativas acidentais de excluir coisas que não podem ser apagadas e esclarece a intenção do desenvolvedor.

// Non-strict: attempt silently fails
var a = 1;
delete a; // false; a still exists

// Strict: SyntaxError
'use strict';
var a = 1;
delete a; // SyntaxError: Delete of an unqualified identifier in strict mode

Melhorias adicionais de segurança e desempenho

Além das restrições específicas, o modo estrito permite que os motores JavaScript realizem certas otimizações que são impossíveis. Como o modo estrito elimina alguns comportamentos dinâmicos (como a instrução e global implícito), o motor pode prever melhor como as variáveis serão usadas, levando a uma execução mais rápida em alguns casos. Além disso, o modo estrito desativa a propriedade e a propriedade , que foram historicamente usadas para introspecção, mas também apresentaram riscos de segurança ao permitir o acesso à pilha de chamadas. Esta restrição reforça a encapsulamento e previne certos tipos de ataques.

Exemplos práticos de modo rígido em ação

Para solidificar a compreensão, vamos percorrer uma série de exemplos que contrastam o modo desleixado com o modo estrito. Estes demonstram o modo de feedback imediato que o modo rigoroso fornece.

Exemplo 1: Atribuição Variável Não Declarada

// sloppy.js
function userInfo() {
 name = "John"; // silently creates global 'name'
}
userInfo();
console.log(window.name); // "John" (in browsers)

// strict.js
'use strict';
function userInfo() {
 name = "John"; // ReferenceError: name is not defined
}
userInfo();

Sem modo estrito, um simples erro de digitação como em vez de pode poluir o escopo global. Com o modo rígido, o erro é capturado instantaneamente.

Exemplo 2: Atribuição de uma propriedade global somente leitura

// sloppy mode
undefined = 5; // silently fails (undefined remains undefined)
NaN = 6; // silently fails
console.log(undefined, NaN); // undefined, NaN

// strict mode
'use strict';
undefined = 5; // TypeError: Cannot assign to read-only property 'undefined' of object '#<Window>'
NaN = 6; // TypeError

Modo rigoroso evita a sobreposição acidental de constantes globais que nunca devem mudar, ajudando a preservar a integridade do ambiente de execução.

Exemplo 3: Duplicar os Nomes da Propriedade do Objecto

No modo estrito, nomes de propriedades duplicadas em literais de objetos causam um . No modo desleixado, o último ganha. Isto é especialmente útil para detectar erros ao editar objetos de configuração ou ao copiar código.

// sloppy: works, last value wins
var config = {
 host: "example.com",
 host: "backup.com" // no error
};
console.log(config.host); // "backup.com"

// strict: SyntaxError
'use strict';
var config = {
 host: "example.com",
 host: "backup.com" // SyntaxError: Duplicate data property in object literal not allowed in strict mode
};

Atropelamentos comuns e migração para o modo estrito

Embora o modo estrito traga muitos benefícios, migrar uma grande base de códigos existente pode apresentar desafios. Alguns padrões mais antigos que foram considerados aceitáveis no ES3/5 podem agora falhar. As questões mais comuns envolvem:

  • Assunções de variáveis não declaradas: Código baseado em globais implícitos deve ser atualizado para declarar variáveis.
  • Usando instruções : Estas devem ser refactoradas em acessos de propriedade explícitos.
  • Literalmente octais : Substituir por ou decimal .
  • Accessando : Isto é proibido; use expressões de função nomeadas em vez disso.
  • Duplicar nomes de parâmetros: Deve ser removido ou renomeado.
  • Usando em variáveis ou funções : Essa operação é proibida.

O processo de migração é muitas vezes incremental. Você pode habilitar a função de modo estrito usando a regra pragma dentro das funções, testar completamente, e então habilitá- lo globalmente uma vez que você está confiante. Ferramentas como o ESLint com sua regra podem ajudar a identificar violações automaticamente. Além disso, usar módulos ou classes ES automaticamente lhe dá comportamento de modo estrito, então migrar para sintaxe moderna é um caminho natural para código mais rigoroso.

Também vale a pena notar que o modo estrito não é um assassino de desempenho. Na verdade, como mencionado, alguns motores podem otimizar melhor o código de modo estrito. A verificação inicial de tempo de execução para a diretiva é insignificante, e a clareza e segurança de código geral superam muito qualquer custo marginal.

Conclusão e Boas Práticas

O modo rígido do JavaScript é uma ferramenta poderosa para escrever código mais robusto, mantendível e seguro. Ao optar por este subconjunto restrito da linguagem, os desenvolvedores ganham detecção precoce de erros comuns, evitam construções perigosas e se beneficiam de melhor desempenho em muitos casos. Habilitar o modo rígido é tão simples quanto adicionar no início de um script ou função, e ele é automaticamente ativo em módulos e classes ES. Os benefícios – evitando globalizações acidentais, eliminando erros silenciosos, restringindo recursos prejudiciais como e – traduzem diretamente em menos bugs e ciclos de depuração mais rápidos.

Para qualquer projeto, seja novo ou legado, adotar o modo rígido deve ser considerado uma boa prática. Comece usando um linter para identificar violações, corrigi-las gradualmente e testá-las com frequência. As ferramentas e frameworks JavaScript modernos geralmente assumem o modo estrito (ou executá-lo), então, alinhar com essa convenção garante compatibilidade e consistência. Ao abraçar o modo estrito, você se junta à comunidade JavaScript mais ampla para priorizar a qualidade e segurança de código.

Para mergulhar mais fundo, consulte a documentação MDN no modo estrito para uma lista completa de restrições e exemplos. Para o contexto histórico, a especificação ECMAScript[] explica as regras formais. Além disso, a regra estrita ESLint[ fornece uma forma automatizada de aplicar o uso consistente em todo o seu projeto. Tornando o modo rígido um hábito pagará dividendos na confiabilidade de código e produtividade do desenvolvedor por anos.