O modo estrito é uma parte importante do JavaScript moderno. É esse modo que permite que os desenvolvedores usem sintaxe mais limitada que a padrão.
A semântica do modo estrito é diferente do modo não estrito tradicional, que às vezes é chamado de "modo superficial". Nesse modo, as regras de sintaxe do idioma não são tão rigorosas e, quando ocorrem alguns erros, o sistema não notifica o usuário sobre eles. Ou seja, os erros podem ser ignorados e o código em que são feitos pode ser executado ainda mais. Isso pode levar a resultados inesperados de execução de código.

O modo estrito introduz algumas alterações na semântica do JavaScript. Impede que o sistema feche os olhos para erros, lançando exceções apropriadas. Isso faz com que a execução do programa pare.
Além disso, o modo estrito ajuda a escrever programas nos quais não há deficiências que impedem que os mecanismos JS otimizem o código. Além disso, neste modo, é proibido o uso de elementos de sintaxe que possam obter um significado especial em versões futuras do idioma.
Recursos do uso do modo estrito
O modo estrito pode ser aplicado a funções individuais ou a um script inteiro. Ele não pode ser aplicado apenas a instruções individuais ou a blocos de código entre chaves. Para usar o modo estrito no nível de todo o script, no início do arquivo, antes de qualquer outro comando, você deve colocar o
"use strict"
ou
'use strict'
construção
'use strict'
.
Se o projeto tiver alguns scripts que não usam o modo estrito e outros que usam esse modo, pode acontecer que esses scripts sejam mesclados.
Isso levará ao fato de que o código que não se destina a ser executado no modo estrito estará nesse estado quando o sistema tentar executá-lo no modo estrito. O inverso também é possível - o código escrito para o modo estrito entrará no modo não estrito. Portanto, é melhor não misturar scripts "estritos" e "não estritos".
Como já mencionado, o modo estrito pode ser aplicado a funções individuais. Para fazer isso - a construção
"use strict"
ou
'use strict'
deve ser colocada na parte superior do corpo da função, antes de qualquer outro comando. O modo estrito com essa abordagem se aplica a tudo que é colocado no corpo da função, incluindo funções aninhadas.
Por exemplo:
const strictFunction = ()=>{ 'use strict'; const nestedFunction = ()=>{
Nos módulos JavaScript que apareceram no padrão ES2015, o modo estrito é ativado por padrão. Portanto, ao trabalhar com eles, você não precisa incluí-lo explicitamente.
Alterações introduzidas no código JS pelo modo estrito
O modo estrito afeta a sintaxe do código e a maneira como o código se comporta durante a execução do programa. Erros no código são convertidos em exceções. O fato de que no modo silencioso trava silenciosamente no modo estrito causa uma mensagem de erro. É semelhante à maneira como o sistema responde aos erros de sintaxe no modo lax. No modo estrito, o trabalho com variáveis é simplificado, o uso da função
eval
e do objeto de
arguments
é fortemente regulamentado, e o trabalho com construções que podem ser implementadas em versões futuras da linguagem é simplificado.
▍ Converter erros silenciosos em exceções
Erros silenciosos são convertidos no modo estrito em exceções. No modo relaxado, o sistema não responde explicitamente a esses erros. No modo estrito, a presença de tais erros leva à inoperabilidade do código.
Portanto, graças a isso, é difícil cometer o erro de declarar acidentalmente uma variável global, pois variáveis e constantes no modo estrito não podem ser declaradas sem o uso das diretivas
var
,
let
ou
const
. Como resultado, a criação de variáveis sem essas diretivas levará à inoperabilidade do programa. Por exemplo, tentar executar o seguinte código lançará uma exceção
ReferenceError
:
'use strict'; badVariable = 1;
Esse código não pode ser executado no modo estrito, pois se o modo estrito fosse desativado, criaria a variável global
badVariable
. O modo estrito protege o programador de criar inadvertidamente variáveis globais.
Uma tentativa de executar qualquer código que, no modo normal, simplesmente não funcione, agora gera uma exceção. Os erros são considerados quaisquer construções sintáticas incorretas que foram simplesmente ignoradas no modo lax.
Portanto, por exemplo, no modo estrito, você não pode executar operações de atribuição de valor em entidades somente leitura, como
arguments
,
NaN
ou
eval
.
No modo estrito, uma exceção, por exemplo, será lançada nos seguintes casos:
- uma tentativa de atribuir um valor a uma propriedade somente leitura, como algum tipo de propriedade global regravável;
- uma tentativa de escrever um valor para uma propriedade que possui apenas um getter;
- Uma tentativa de escrever algo em uma propriedade de um objeto não extensível.
Aqui estão exemplos de construções de sintaxe que levam a exceções no modo estrito:
'use strict'; let undefined = 5; let Infinity = 5; let obj = {}; Object.defineProperty(obj, 'foo', { value: 1, writable: false }); obj.foo = 1 let obj2 = { get foo() { return 17; } }; obj2.foo = 2 let fixedObj = {}; Object.preventExtensions(fixedObj); fixed.bar= 1;
Tentar executar esses fragmentos de código no modo estrito lançará uma exceção
TypeError
. Por exemplo,
undefined
e
Infinity
são entidades globais cujos valores não podem ser substituídos, e a propriedade
foo
do objeto
obj
não suporta reescrita. A propriedade
foo
do
obj2
tem apenas um getter. O objeto
fixedObj
tornado não extensível usando o método
Object.preventExtensions
.
Uma tentativa de excluir uma
TypeError
não
TypeError
também resultará em
TypeError
:
'use strict'; delete Array.prototype
O modo estrito proíbe atribuir propriedades com o mesmo nome a um objeto. Como resultado, uma tentativa de executar o seguinte código resultará em um erro de sintaxe:
'use strict'; let o = { a: 1, a: 2 };
O modo estrito requer que os nomes dos parâmetros das funções sejam exclusivos. No modo não estrito, se, por exemplo, dois parâmetros de função tiverem o mesmo nome,
one
, ao passar a função de argumento, o valor do parâmetro será o que caiu no argumento declarado por último.
No modo estrito, os parâmetros de funções com o mesmo nome são proibidos. Como resultado, uma tentativa de executar o seguinte código resultará em um erro de sintaxe:
'use strict'; const multiply = (x, x, y) => x*x*y;
No modo estrito, você não pode usar a notação octal de números, precedendo o número com zero. Isso não está na especificação, mas esse recurso é suportado pelos navegadores.
Esse estado de coisas confunde os desenvolvedores, forçando-os a acreditar que o 0 que antecede o número é simplesmente ignorado, sem muito sentido. No modo estrito, tentar usar um número no início igual a 0 resultará em um erro de sintaxe.
O modo estrito também proíbe o uso de construções que impedem a otimização. O intérprete, antes de executar a otimização do código, precisa saber que a variável é armazenada exatamente onde, de acordo com o intérprete, é armazenada. No modo estrito, coisas que interferem nas otimizações são proibidas.
Um exemplo dessa proibição diz respeito à declaração
with
. Se você usar esta instrução, isso impedirá que o interpretador JS descubra a qual variável ou a qual propriedade estamos nos referindo, pois é possível que uma entidade com o mesmo nome exista fora e dentro do bloco da instrução
with
.
Suponha que exista um código como este:
let x = 1; with (obj) { x; }
O intérprete não poderá descobrir se a variável
x
localizada dentro do bloco
with
se refere à variável externa
x
ou à propriedade
obj.x
do objeto
obj
.
Como resultado, não está claro exatamente onde o valor
x
estará localizado na memória. Para se livrar de tais ambiguidades, no modo estrito é proibido o uso da declaração
with
. Vamos ver o que acontece se você tentar executar o seguinte código no modo estrito:
'use strict'; let x = 1; with (obj) { x; }
O resultado desta tentativa será um erro de sintaxe.
Mesmo no modo estrito, é proibido declarar variáveis no código passado para o método
eval
.
Por exemplo, no modo normal, um comando no formato
eval('let x')
resultará na declaração da variável
x
. Isso permite que os programadores ocultem declarações de variáveis em strings, o que pode levar à substituição das definições das mesmas variáveis fora de
eval
.
Para evitar isso, no modo estrito, é proibido declarar variáveis no código passadas como uma string para o método
eval
.
O modo estrito também proíbe a exclusão de variáveis regulares. Como resultado, a tentativa de executar o seguinte código resultará em um erro de sintaxe:
'use strict'; let x; delete x;
▍ Proibindo construções de sintaxe incorretas
No modo estrito,
arguments
proibido o uso incorreto de avaliação e
arguments
. Esta é uma proibição de todos os tipos de manipulação com eles. Por exemplo, isso é algo como atribuir novos valores a eles, usando seus nomes como nomes de variáveis, funções e parâmetros de funções.
Aqui estão exemplos de uso indevido de avaliação e
arguments
:
'use strict'; eval = 1; arguments++; arguments--; ++eval; eval--; let obj = { set p(arguments) { } }; let eval; try { } catch (arguments) { } try { } catch (eval) { } function x(eval) { } function arguments() { } let y = function eval() { }; let eval = ()=>{ }; let f = new Function('arguments', "'use strict'; return 1;");
No modo estrito, você não pode criar aliases para o objeto de
arguments
e definir novos valores de
arguments
por meio desses aliases.
No modo normal, se o primeiro parâmetro da função for
a
, a configuração do valor de
a
no código da função também levará a uma alteração no valor nos
arguments[0]
. No modo estrito, os
arguments
sempre conterão a lista de argumentos com os quais a função foi chamada.
Suponha que você tenha o seguinte código:
const fn = function(a) { 'use strict'; a = 2; return [a, arguments[0]]; } console.log(fn(1))
O console receberá
[2,1]
. Isso ocorre porque escrever um valor de 2 em
a
não escreve um valor de 2 em
arguments[0]
.
PtOtimize o desempenho
No modo estrito, a propriedade
arguments.callee
não é suportada. No modo normal, ele retorna o nome da função pai da função cuja propriedade
callee
dos objetos de
arguments
que estamos examinando.
O suporte a essa propriedade interfere nas otimizações, como funções embutidas, uma vez que o uso de
arguments.callee
requer a disponibilidade de uma referência a uma função não incorporada ao acessar esta propriedade. No modo estrito, o uso de
arguments.callee
gera uma exceção
TypeError
.
No modo estrito, a
this
nem sempre precisa ser um objeto. Em circunstâncias normais, se
this
função estiver vinculada, usando
call
,
apply
ou
bind
, a algo que não seja um objeto, a um valor de um tipo primitivo como
undefined
,
null
,
number
ou
boolean
, esse valor deverá ser um objeto.
Se o contexto
this
mudar para algo que não é um objeto, um objeto global substituirá. Por exemplo,
window
. Isso significa que, se você chamar uma função, definindo
this
como um valor que não é um objeto, em vez desse valor, uma referência ao objeto global será incluída.
Considere um exemplo:
'use strict'; function fn() { return this; } console.log(fn() === undefined); console.log(fn.call(2) === 2); console.log(fn.apply(null) === null); console.log(fn.call(undefined) === undefined); console.log(fn.bind(true)() === true);
Todos os comandos
console.log
serão emitidos como
true
, porque no modo estrito o valor
this
na função não é automaticamente substituído por uma referência ao objeto global se
this
definido como um valor que não é um objeto.
Changes Alterações relacionadas à segurança
No modo estrito, você não pode tornar públicas as propriedades da função de
caller
e
arguments
. O fato é que o
caller
, por exemplo, pode dar acesso à função que chamou a função cuja propriedade do
caller
estamos acessando.
O objeto
arguments
armazena os argumentos passados para a função quando ela foi chamada. Por exemplo, se tivermos uma função
fn
, isso significa que, por meio de
fn.caller
você pode acessar a função que chamou a função e, usando
fn.arguments
pode ver os argumentos passados para
fn
quando foi chamado.
Esses recursos representam um risco potencial à segurança. Como resultado, o acesso a essas propriedades é proibido no modo estrito.
function secretFunction() { 'use strict'; secretFunction.caller; secretFunction.arguments; } function restrictedRunner() { return secretFunction(); } restrictedRunner();
No exemplo anterior, não podemos, no modo estrito, acessar
secretFunction.caller
e
secretFunction.arguments
. O fato é que essas propriedades podem ser usadas para obter uma pilha de chamadas de função. Se você tentar executar esse código, uma exceção
TypeError
será
TypeError
.
No modo estrito, identificadores que podem ser usados em versões futuras do JavaScript não podem ser usados para nomear variáveis ou propriedades de objetos. Por exemplo, estamos falando dos seguintes identificadores:
implements
,
interface
,
let
,
package
,
private
,
protected
,
public
,
static
e
yield
.
No ES2015 e em versões posteriores do padrão, esses identificadores se tornaram palavras reservadas. E eles não podem ser usados para nomear variáveis ou propriedades no modo estrito.
Sumário
O modo estrito é um padrão que existe há muitos anos. Goza de suporte extremamente amplo ao navegador. Problemas com o código de modo estrito podem ocorrer apenas em navegadores mais antigos, como o Internet Explorer.
Navegadores modernos não devem ter dificuldades com o modo JavaScript estrito. Como resultado, podemos dizer que esse modo deve ser usado para evitar erros "silenciosos" e aumentar a segurança do aplicativo. Erros silenciosos são convertidos em exceções que impedem a execução de programas e, em termos de melhoria da segurança, por exemplo, podem ser observados mecanismos de modo estrito que restringem a avaliação e impedem o acesso à pilha de chamadas de função. Além disso, o uso do modo estrito facilita a otimização do código do mecanismo JS e força o programador a manipular cuidadosamente palavras reservadas que podem ser usadas em versões futuras do JavaScript.
Caros leitores! Você usa o modo estrito ao escrever o código JS para seus projetos?
