Executando verificação de segurança...
Em resposta a [Não disponível]
4

Complementando:


Parâmetros opcionais

No caso de parâmetro opcional, também daria para usar um valor default assim:

function saudacao(nome = 'visitante') {
    alert(nome);
}

Só fica um pouco complicado para vários parâmetros. Por exemplo, se todos são opcionais mas eu só quero mudar o segundo:

function saudacao(saudacao = 'Olá', nome = 'visitante') {
    alert(`${saudacao}, ${nome}`);
}

// assim ok, usa os valores default
saudacao(); // Olá, visitante

// se quiser mudar só o nome, não dá, pois o primeiro parâmetro sempre é a saudação
saudacao('fulano'); // fulano, visitante

// nesse caso, poderia fazer como vc sugeriu
function saudacao2(saudacao, nome) {
    saudacao ||= 'Olá';
    nome ||= 'visitante';
    alert(`${saudacao}, ${nome}`);
}

// Aí basta passar null para indicar que quero usar o valor default
saudacao2(null, 'fulano'); // Olá, fulano

Ou então usar desestruturação (que fica um pouco mais chato caso precise passar todos os parâmetros, ainda mais se tiver vários; só vale a pena se for mais frequente as chamadas mudando um ou outro):

function saudacao({ saudacao, nome }) {
    saudacao ||= 'Olá';
    nome ||= 'visitante';
    alert(`${saudacao}, ${nome}`);
}

// mudar somente o nome
saudacao({ nome: 'fulano'}); // Olá, fulano

Converter string HTML para elemento

Já para converter string HTML em um elemento, você pode usar o elemento template. A documentação diz que ele é um "mecanismo para conter HTML que não será renderizado imediatamente na página", ou seja, me parece mais adequado para o caso em questão (fica menos com cara de "gambiarra", na minha opinião):

function evalHTML(string) {
    let template = document.createElement("template");
    template.innerHTML = string;
    return template.content.children[0];
}

O retorno acaba sendo igual à sua função, mas acho que a semântica fica mais adequada, já que um elemento qualquer (a, div) poderia deixar ligeiramente mais confuso ("por que tá usando um link?", etc).


Iteráveis e for..of

Sobre iteráveis e for..of, vale lembrar que também se aplica a strings:

const texto = 'abc 123';
// itera pelos caracteres da string
for (const caractere of texto) {
    console.log(caractere);
}

Lembrando que isso pode dar diferença com o for tradicional, dependendo do conteúdo da string:

// sim, posso colocar um emoji direto no código
const texto = '💩';
// ou, se seu editor não suporta, pode trocar por
// const texto = String.fromCodePoint(0x1f4a9);

console.log('iterando com for..of');
for (const caractere of texto) {
    console.log(caractere);
}

console.log('iterando com for tradicional');
for (let i = 0; i < texto.length; i++) {
    console.log(texto[i]);
}

A saída é:

iterando com for..of
💩
iterando com for tradicional
�
�

Caso tenha ficado curioso, a explicação está aqui.


Iterar por objeto

Para iterar as chaves e valores de um objeto, também pode usar Object.entries, que já te dá as chaves e valores ao mesmo tempo:

let objeto = {
  'chave 1': 42,
  'chave 2': 3.14,
  'chave 3': 9.8,
}

for (const [chave, valor] of Object.entries(objeto)) {
    console.log(`${chave} = ${valor}`);
}

Saída:

chave 1 = 42
chave 2 = 3.14
chave 3 = 9.8
Carregando publicação patrocinada...
2

Vim para falar do default parameter e você já havia postado. Só complementando, ele tem 95% de compatibilidade, basicamente é aceito por todos os navegadores modernos nas versões mais atuais, só não há suporte para o Internet Explorer em nenhuma versão (não que eu ligue, rs).

Quando se usa um transpiler internamente ele substitui esse default parameter para evitar incompatibilidades.

0
Conteúdo excluído
1

Até onde vi, os parâmetros default não tem otimização, já que são avaliados sempre que a função é chamada. Ex:

function f() {
    console.log('chamando f');
    return 42;
}

function g(a = f()) {
    console.log('g -> a=', a);
}

function h(a) {
    a ||= f();
    console.log('h -> a=', a);
}

var n = 3;
console.log('chamando g várias vezes');
for (var i = 0; i < n; i++) {
    g();
}

console.log('chamando h várias vezes');
for (var i = 0; i < n; i++) {
    h();
}

Saída:

chamando g várias vezes
chamando f
g -> a= 42
chamando f
g -> a= 42
chamando f
g -> a= 42
chamando h várias vezes
chamando f
h -> a= 42
chamando f
h -> a= 42
chamando f
h -> a= 42

Repare que f() sempre é chamada em todas as invocações de ambas as funções g e h.

Creio que o ganho do parâmetro default é deixar mais claro na própria lista de parâmetros que eles possuem um valor default (em vez de precisar entrar no código da função pra ver isso).


Mas tem uma diferença importante, se você passar null ou undefined para as funções.

Por exemplo, se tivermos:

function f(x = 1) {
    return x;
}

function g(x) {
    x ||= 1;
    return x;
}

Se chamarmos f() e g(), o resultado é 1 em ambas. Se chamar f(2) e g(2), o resultado é 2, e até aí ok.

Mas se passarmos null ou undefined:

for (const value of [null, undefined]) {
    console.log(`${value} -> f=${f(value)}  g=${g(value)}`);
}

f(null) retorna null, pois ele entende que foi passado um argumento. Já se chamarmos f(undefined), ele entende que o argumento não foi passado e seta o valor para 1. Já g retorna 1 em ambos os casos, pois o operador || considera tanto null quanto undefined como "falso", e aí ele seta o valor para 1.

Por isso a saída é:

null -> f=null  g=1
undefined -> f=1  g=1
Conteúdo excluído
1

Não vai ficar muito comprido? Eu acho que fica melhor como está, o post principal com alguns exemplos de vários assuntos, e outro só complementando alguns casos.

Conteúdo excluído