创建模块的常见做法是将它们封装在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上的原创博客文章。