Nós já chegamos a falar deste assunto em outro artigo, porém o JavaScript nunca deixa de nos surpreender!
Nesta segunda parte do artigo sobre APIs desconhecidas do JavaScript, vamos tocar em alguns outros pontos interessantes que podem facilitar muito o desenvolvimento de suas aplicações.
Tagged Template Literals
Os tagged templates estão mais presentes se você já usou styled-components no React, mas em essência, o tagged literals permitem que você tenha mais controle sobre sua string.
taggingFn`Olá! Meu nome é ${name}`
A palavra taggingFn é, na verdade, uma função com a seguinte assinatura:
function taggingFn (strings, ...values) {
console.log(strings) // [ 'Olá! Meu nome é ', '' ]
console.log(values) // [ 'Lucas' ]
}
const name = 'Lucas'
taggingFn`Olá! Meu nome é ${name}`
Com isso podemos manipular a string e fazer o que quisermos com os valores.
Comma Operator
Este operador é realmente bem pouco conhecido, o que ele faz é simplesmente separar todas as expressões e retornar somente a última expressão da cadeia como um todo:
let expression = (1, 2, 3)
console.log(expression) // 3
O que temos aqui é que todas as expressões sofrem um eval e somente o último é enviado para o valor de expression. A usabilidade desse tipo de operador é mais relacionada a execução de funções curtas, parecidas com expressões lambda.
Vamos supor que queremos inserir uma série de itens concatenados em um array e depois queremos retornar este array para quem está chamando:
const pushItems = (arr, ...items) => (arr.push(...items), arr)
const a = pushItems([], 1,2,3,4)
console.log(a) // [1,2,3,4]
Reduzindo a quantidade de itens de um array sem delete
O jeito padrão que usamos atualmente para reduzir um array removendo seus itens é o clássico delete:
const arr = [1,2,3]
delete arr[2]
console.log(arr) // [ 1, 2, <1 empty item> ]
Porém note que, mesmo removendo o item, o array ainda tem espaço de alocação para 3 itens, e um deles está vazio. Para poder resolver este problema, geralmente criamos um filter para remover itens nulos logo em seguida:
const arr = [1,2,3]
delete arr[2]
console.log(arr.filter((i) => !!i)) [ 1, 2 ]
Porém existe um método mais simples, usando o length. É de senso comum que o array.length é uma propriedade do array que mostra a quantidade de itens que existe no mesmo, porém, o que poucos sabem é que é possível alterar esse número, e a alteração deste número leva a redução de itens do array a partir do último, então o nosso código anterior poderia ser escrito assim:
const arr = [1,2,3]
arr.length = 2
console.log(arr) // [ 1, 2 ]
Veja que o array original tinha um length de 3, quando alteramos o valor para 2, removemos o último item e não deixamos espaços desalocados.
Se fizermos o oposto, vamos poder aumentar a capacidade do array colocando <empty items> novos:
const arr = [1,2,3]
arr.length = 4
console.log(arr) // [ 1, 2, <1 empty item>, <1 empty item> ]
Instanciamento direto
Estamos acostumados a instanciar novos objetos usando a notação () certo? Por exemplo:
class A {
method () {
console.log('A')
}
}
const a = new A()
a.method() // A
Ou então
(new A()).method() // A
Porém, quando estamos usando a segunda notação, os parenteses são completamente opcionais:
(new A).method() // A
(new Date).toISOString()
const a = new A
Void Operator
O operador void faz com que qualquer expressão que venha após ele seja avaliada, executada, mas seu retorno é suprimido e, ao invés disso, retornamos undefined.
class A {
method () {
return 'A'
}
}
const a = new A
console.log(void a.method()) // undefined
Mesmo que estejamos explicitamente retornando alguma coisa, o void anula esse retorno e nos dá sempre undefined. Este operador existe porque, antigamente, poderíamos associar o undefined a outro valor no JS, o que transformava o mesmo em outro objeto, então o operador void foi criado para poder dar certeza absoluta do retorno.
Veja a documentação oficial
Operador Unário +
O operador + converte o seu operando para o tipo Number.
+"12" // 12
+{} // NaN
+null // 0
+undefined // NaN
+ { valueOf: () => 22 } // 22
+"something" // NaN
Este é um operador muito interessante quando queremos conversões de variáveis mais rápidas sem precisar de um parseInt:
const obj = {
port: +(process.env.PORT || 8080)
}
Operador unário –
Faz exatamente a mesma coisa que o + porém após a conversão do operador para um Number ele é negado.
-"12" // -12
-{} // NaN
-null // -0
-undefined // NaN
- { valueOf: () => 22 } // -22
-"something" // NaN
Se o resultado da conversão for NaN a negação não vai ser aplicada
O JS tem três tipos de 0’s, o 0 tradicional, o -0 e +0. Todos são basicamente a mesma coisa, quando negamos +0 produzimos -0 e, negando -0 produzimos +0.
- +0 // -0
- -0 // 0
Conclusão
Não importa o quanto saibamos de JavaScript sempre vamos ter alguma coisa nova para aprender!
Se você conhece outra feature legal do JavaScript, aproveita e manda aqui pra gente nos comentários!