Diferença entre usar nulo vs quebra automática de parênteses para a função nula IIFE () vs (function ())

A prática comum para criar módulos é envolvê-los em parênteses, para que você não vaze nenhuma variável fora do módulo (ao concatenar etc).

Há tambémvoid operador, que avalia uma determinada expressão e retornaundefined. (Veja emMDN)

Gostaria de saber qual é a razão por trás de preferir funções de quebra de parênteses em vez de usarvoid. É histórico, algo relacionado à concatenação?

Sei que você pode ter problemas com a concatenação quando um dos arquivos tem um ponto-e-vírgula ausente, causando problemas desagradáveis até você perceber.

Exemplos

Digamos, module1.js (observe a vírgula ausente):

(function () {
    return function () {
        console.log('module1. I should not be called');
    };
})()

e module2.js:

(function () {
    return function () {
        console.log('module2. I should not be called either');
    };
})();

Se você concatenar esses scripts em um pacote, ele produzirá o seguinte:

(function () {
    return function () {
        console.log('module1. I should not be called');
    };
})()(function () {
    return function () {
        console.log('module2. I should not be called either');
    };
})();

Como os dois módulos (arquivos) retornam uma função, o segundo supostamente IIFE se torna uma invocação dovalor de retorno do primeiro módulo, chamando efetivamenteconsole.log. A solução comum para isso é declarar seu módulo com!(function (){})(); o que força o valor retornado a ser um booleano.

Se, no entanto, você deveria usarvoid, gostar:

void function () {
    return function () {
        console.log('module1. I should not be called');
    };
}()

O arquivo concatenado ainda estará errado, mas você notará o erro na primeira execução, portanto, mais facilmente percebido. Ver abaixo.

void function () {
    return function () {
        console.log('module1. I should not be called');
    };
}()void function () {
    return function () {
        console.log('module2. I should not be called either');
    };
});

Isso jogaUnexpected token void. No que diz respeito aos módulos, acredito!(function(){}() evoid function(){}() alcançar o mesmo efeito. Mas eu sinto quevoid parece mais limpo (subjetivo) do que agrupar uma função com parâmetros e anexar! para isso.

Estou faltando alguma coisa? Não seria melhor se usássemosvoid?

questionAnswers(1)

yourAnswerToTheQuestion