对于IIFE void function()与(function()),使用void与在parens中换行之间的区别

Difference between using void vs wrapping in parens for IIFE void function() vs (function())

本文关键字:void function 换行 之间 区别 parens IIFE 对于 使用 与在      更新时间:2023-09-26

创建模块的常见做法是将它们封装在parens中,这样就不会将任何变量泄漏到模块之外(连接等时)。

还有void运算符,它计算给定的表达式并返回undefined。(参见MDN)

我想知道为什么更喜欢在parens中包装函数而不是使用void。它是历史性的,是与串联有关的吗

我知道,当其中一个文件缺少分号时,连接可能会出现问题,导致严重的问题,直到你注意到为止。

示例

比如,module1.js(注意缺少逗号):

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

和,module2.js:

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

如果您将这些脚本连接到一个捆绑包中,它将生成以下内容:

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

由于两个模块(文件)都返回一个函数,因此第二个IIFE会调用第一个模块的返回值,从而有效地调用console.log。常见的解决方法是用!(function (){})();声明模块,强制返回值为布尔值。

但是,如果要使用void,例如:

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

连接的文件仍然是错误的,但您会在第一次运行时注意到错误,因此更容易被注意到。请参见下文。

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');
    };
});

这抛出Unexpected token void。就模块而言,我相信!(function(){}()void function(){}()达到了相同的效果。但我觉得void看起来更干净(主观),而不是用params包装一个函数并在它前面加上!

我错过了什么?如果我们使用void不是更好吗

许多JavaScript程序员认为void是令人困惑和多余的,尤其是Douglas Crockford,他称其为JavaScript的"坏部分"之一。

在函数定义之前加上void可能特别令人困惑。在C++等语言中,它的意思是"这是一种不返回值的函数类型"。在JavaScript中,void不定义任何内容;相反,它评估函数(或其他表达式)并返回值undefined。所以你在JavaScript代码中看不到太多。

有关在模块前面使用!的更多信息,请查看此StackOverflow答案。

此外,请务必阅读Ben Allman在IIFE上的原创博客文章。