O JavaScript é frequentemente chamado de linguagem mais simples para iniciantes, em programação que é a mais difícil de obter domínio. O autor do material, cuja tradução publicamos, diz que não pode deixar de concordar com esta afirmação. O problema é que o JS é uma linguagem muito antiga e muito flexível. Está cheio de misteriosas construções sintáticas e características obsoletas que ainda suporta.

Hoje falaremos sobre os recursos e opções pouco conhecidos do JavaScript para sua aplicação prática.
JavaScript é sempre algo novo
Trabalho com JavaScript há muitos anos e constantemente me deparo com algo que nunca suspeitei que existisse. Aqui, tentei listar recursos pouco conhecidos semelhantes da linguagem. No modo estrito, alguns deles não funcionarão, mas no modo normal, são amostras de código JS completamente corretas. Note-se que não pretendo aconselhar os leitores a colocar tudo isso em serviço. Embora o que eu vou falar pareça muito interessante para você, você pode começar a usar tudo isso se trabalhar em equipe e, para dizer o mínimo, surpreender seus colegas.
→ O código que discutiremos
aqui pode ser encontrado
aqui.Observe que não incluí coisas como aumento de variáveis, fechamentos, objetos proxy, herança de protótipo, assíncrono / espera, geradores e similares. Embora esses recursos da linguagem possam ser atribuídos a difíceis de entender, eles não são bem conhecidos.
Operador de anulação
JavaScript tem um operador
void
unário. Você pode ter encontrado ele na forma de
void(0)
ou
void 0
. Seu único objetivo é calcular a expressão à sua direita e retornar
undefined
.
0
aqui é usado simplesmente porque é habitual, embora isso não seja necessário, e aqui você pode usar qualquer expressão válida. É verdade que, em qualquer caso, esse operador retornará
undefined
.
Por que adicionar uma palavra-chave especial ao idioma que serve para retornar
undefined
, se você pode apenas usar o valor padrão
undefined
? Não é, existe alguma redundância?
Como se viu, antes da aparência do padrão ES5 na maioria dos navegadores, um valor padrão de
undefined
poderia receber um novo valor. Digamos que você possa executar com sucesso este comando:
undefined = "abc"
. Como resultado, um valor
undefined
pode não ser o que deveria ser. Naqueles dias, o uso de
void
nos permitiu garantir a confiança no uso do real
undefined
.
Parênteses ao chamar construtores são opcionais
Os colchetes que são adicionados após o nome da classe, invocando o construtor, são completamente opcionais (a menos que o construtor precise passar argumentos).
No exemplo a seguir, a presença ou ausência de parênteses não afeta a operação correta do programa.
Os suportes não podem ser usados com IIFE
A sintaxe IIFE sempre me pareceu estranha. Por que existem todos esses colchetes?
Como se viu, os colchetes são necessários apenas para informar ao analisador JavaScript que algum código é uma expressão funcional e não uma tentativa incorreta de declarar uma função. Conhecer esse fato nos permite entender que existem muitas maneiras de se livrar dos colchetes nos quais o IIFE está incluído e, ao mesmo tempo, escrever código de trabalho.
Aqui, o operador
void
diz ao analisador que o código a seguir é uma expressão funcional. Isso torna possível se livrar dos colchetes em torno da declaração da função. A propósito, aqui você pode usar qualquer operador unário (
void
,
+
,
!
,
-
e assim por diante), e o código continuará funcionando. Isso não é maravilhoso?
No entanto, se você é um leitor atento, pode se perguntar se o operador unário afeta o resultado retornado pelo IIFE. De fato, do jeito que está. Mas o bom é que, se você precisar do resultado do IIFE, que você armazena em uma variável, por exemplo, não precisará de parênteses em torno do IIFE. Aqui está um exemplo.
As chaves ao redor do primeiro IIFE apenas melhoram a legibilidade do código sem afetar sua operação.
Se você deseja entender melhor o IIFE, dê uma olhada
neste material.
Construção com
Você sabia que o JavaScript possui uma construção
with
que suporta blocos de expressão? É assim:
with (object) statement
A construção
with
adiciona todas as propriedades do objeto transmitidas a ele na cadeia de escopo usada ao executar os comandos.
with
pode parecer uma ótima ferramenta. Parece que é ainda melhor do que os novos recursos de JS para
destruição de objetos , mas na verdade não é.
A construção
with
foi descontinuada e não é recomendada para uso. No modo estrito, seu uso é proibido. Acontece que os blocos causam problemas de desempenho e segurança.
Construtor de Função
Usar a palavra-chave
function
não é a única maneira de definir uma nova função. Você pode definir funções dinamicamente usando o construtor
Function
e o
new
operador. Aqui está como fica.
O último argumento passado ao construtor é uma sequência com o código da função. Dois outros argumentos são parâmetros de função.
É interessante notar que o construtor
Function
é o "pai" de todos os construtores em JavaScript. Até o construtor
Object
é um construtor
Function
. E o construtor nativo de
Function
também é
Function
. Como resultado, uma chamada do tipo
object.constructor.constructor...
feita para qualquer objeto JS um número suficiente de vezes retornará o construtor
Function
como resultado.
Propriedades do Recurso
Todos sabemos que funções em JavaScript são objetos de primeira classe. Portanto, ninguém está nos impedindo de adicionar novas propriedades às funções. Isso é perfeitamente normal, mas isso raramente é usado.
Quando isso pode ser necessário?
De fato, existem várias situações em que esse recurso pode ser útil. Considere-os.
▍ Recursos personalizados
Suponha que tenhamos uma função
greet()
. Precisamos que ela exiba diferentes mensagens de boas-vindas, dependendo das configurações regionais usadas. Essas configurações podem ser armazenadas em uma variável externa à função. Além disso, a função pode ter uma propriedade que define essas configurações, em particular as configurações de idioma do usuário. Usaremos a segunda abordagem.
WithFunções com variáveis estáticas
Aqui está outro exemplo semelhante. Suponha que precisamos implementar um certo gerador que produz uma sequência de números ordenados. Normalmente, nessas situações, para armazenar informações sobre o último número gerado, são utilizadas variáveis de contador estático nas classes ou IIFE. Com essa abordagem, restringimos o acesso ao balcão e evitamos a poluição do escopo global com variáveis adicionais.
Mas e se precisarmos de flexibilidade, se precisarmos ler ou mesmo modificar o valor desse contador e não entupir o escopo global?
Obviamente, você pode criar uma classe com a variável correspondente e com métodos que permitem trabalhar com ela. Ou você não pode se preocupar com essas coisas e apenas usar as propriedades das funções.
Propriedades do objeto Arguments
Estou certo de que a maioria de vocês sabe que funções têm um objeto de
arguments
. Este é um objeto semelhante a um array acessível em todas as funções (com exceção das funções de seta, que não possuem seus próprios objetos de
arguments
). Ele contém uma lista de argumentos passados para a função quando foi chamada. Além disso, possui algumas propriedades interessantes:
arguments.callee
contém um link para a função atual.arguments.caller
contém uma referência à função que chamou a função atual.
Considere um exemplo.
O padrão ES5 proíbe o uso de propriedades de
caller
e
caller
no modo estrito, mas elas ainda são amplamente encontradas em muitos textos de programas compilados por JavaScript, por exemplo, em bibliotecas. Portanto, é útil saber sobre eles.
Literais de modelo com a tag
Certamente você, se tiver algo a ver com a programação JavaScript, já ouviu falar em
literais de
modelos . Literais de modelo são uma das muitas grandes inovações do padrão ES6. No entanto, você sabe sobre literais de modelo com tags?
Os literais de modelo com tags permitem que o desenvolvedor controle como o literal do modelo se transforma em uma sequência. Isso é feito usando tags especiais. Uma tag é apenas o nome de uma função de analisador que recebe uma matriz de cadeias e valores interpretados por um padrão de cadeia. Ao usar uma função de tag, espera-se que ele retorne a string final.
No exemplo a seguir, nossa tag,
highlight
, interpreta os dados de um literal de modelo e os incorpora em uma linha finalizada, colocando-os na tag HTML
<mark>
para selecioná-los quando esse texto é exibido em uma página da web.
Maneiras interessantes de usar esse recurso podem ser encontradas em muitas bibliotecas. Aqui estão alguns exemplos:
Getters e Setters no ES5
Objetos JavaScript, na maioria das vezes, são bastante simples. Suponha que tenhamos um objeto de
user
e estamos tentando acessar sua propriedade
age
usando a construção
user.age
. Com essa abordagem, se essa propriedade for definida, obteremos seu valor e, se não for definido, ficaremos
undefined
. Tudo é muito simples.
Mas trabalhar com propriedades não precisa ser tão primitivo. Objetos JS implementam o conceito de getters e setters. Em vez de retornar diretamente o valor de alguma propriedade do objeto, podemos escrever nossa própria função getter, que retorna o que consideramos necessário. O mesmo se aplica à gravação de novos valores nas propriedades usando as funções do setter.
Os getters e setters permitem implementar esquemas avançados para trabalhar com propriedades. Ao ler ou escrever propriedades, você pode usar os conceitos de campos virtuais, verificar os valores dos campos e, ao escrever ou ler, podem ocorrer alguns efeitos colaterais úteis.
Getters e setters não são inovações padrão do ES5. Eles estavam sempre presentes no idioma. No ES5, apenas ferramentas de sintaxe convenientes foram adicionadas para trabalhar com elas. Detalhes sobre getters e setters podem ser encontrados
aqui .
Exemplos do uso de getters incluem a popular biblioteca Node.j
Colors .
Esta biblioteca
estende a classe String e adiciona muitos métodos getter a ela. Isso permite converter uma string em sua versão "colorida" para que essa string possa ser usada para registro. Isso é feito trabalhando com
propriedades de sequência.
Operador de vírgula
JS tem um operador de vírgula. Permite escrever várias expressões em uma única linha, separadas por vírgula e retornar o resultado da avaliação da última expressão. Aqui está a aparência de tais projetos.
let result = expression1, expression2,... expressionN
Aqui, os valores de todas as expressões serão calculados, após o qual o valor da expressãoN entrará na variável de
result
.
É possível que você já tenha usado o operador de vírgula
for
loops.
for (var a = 0, b = 10; a <= 10; a++, b--)
Às vezes, esse operador é muito útil quando você precisa escrever várias expressões na mesma linha.
function getNextValue() { return counter++, console.log(counter), counter }
Pode ser útil ao projetar pequenas funções de seta.
const getSquare = x => (console.log (x), x * x)
Operador Plus
Se você precisar transformar rapidamente uma sequência em um número, o operador positivo será útil. Ele é capaz de trabalhar com uma variedade de números, e não apenas, como pode parecer, com números positivos. Estamos falando de números negativos, octais, hexadecimais e números em notação exponencial. Além disso, ele pode converter objetos
Date
e Moment.js na biblioteca de data e hora.
Ponto de exclamação duplo
Note-se que o que às vezes é chamado de "operador de ponto de exclamação duplo" (Bang Bang ou Double Bang) não é, de fato, um operador. Este é um operador lógico NOT ou um operador de negação lógica que se parece com um ponto de exclamação repetido duas vezes. O ponto de exclamação duplo é bom porque permite converter qualquer expressão em um valor booleano. Se a expressão, do ponto de vista de JS, for verdadeira - após processá-la com um ponto de exclamação duplo,
true
será retornado. Caso contrário,
false
será retornado.
Operador de negação bit a bit
Vamos ser sinceros: ninguém se importa com operadores bit a bit. Eu não estou falando sobre usá-los. No entanto, o operador de negação bit a bit pode ser usado em muitas situações.
Quando esse operador é aplicado aos números, ele os converte da seguinte forma: a partir do número
N
verifica
N
se
-(N+1)
. Essa expressão fornece
0
se
N
for
-1
.
Esse recurso pode ser usado com o método
indexOf()
quando é usado para verificar a existência de um elemento em uma matriz ou em uma string, pois esse método retorna
-1
se o elemento não for encontrado.
Note-se que nos padrões ES6 e ES7, respectivamente, para strings e matrizes, o método
includes()
apareceu. É definitivamente muito mais conveniente determinar a presença de elementos do que usar o operador de negação bit a bit e
indexOf()
.
Blocos nomeados
O JavaScript tem um conceito de rótulos, com o qual você pode atribuir nomes (rótulos) a loops. Você pode usar esses rótulos para se referir ao loop apropriado ao aplicar instruções de
break
ou
continue
. As etiquetas também podem ser atribuídas a blocos de código regulares.
Loops rotulados são úteis ao trabalhar com loops aninhados. Mas eles também podem ser usados para organizar convenientemente o código em blocos ou ao criar blocos nos quais o código pode ser interrompido.
Observe que, diferentemente de outros idiomas, não existe uma
goto
no JS. Como resultado, os rótulos são usados apenas com instruções de
break
e
continue
.
Sumário
Neste artigo, falamos sobre recursos JavaScript pouco conhecidos, cujo conhecimento é útil para qualquer programador JS, pelo menos para estar pronto para encontrar algo incomum no código de outra pessoa. Se o tópico "JS desconhecido" é interessante para você, você pode dar uma olhada
nesta publicação.
Caros leitores! Se você conhece alguns recursos pouco conhecidos do JS e vê opções para sua aplicação prática, fale-nos sobre eles.
