【发布时间】:2015-05-03 21:36:23
【问题描述】:
创建模块的常见做法是将它们包装在括号中,这样您就不会在模块之外泄漏任何变量(连接时等)。
还有void 运算符,它计算给定的表达式并返回undefined。 (参见MDN)
我想知道为什么更喜欢在括号中包装函数而不是使用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 看起来比使用参数包装函数并在其前面加上 ! 更干净(主观)。
我错过了什么?如果我们使用void会不会更好?
【问题讨论】:
-
解决问题的正确方法是将分号放在它所属的位置,而不是选择不同的模块头。
-
@Bergi 你错过了 OP 的全部要点!他专门尝试使代码对潜在的人为错误更加健壮,而您的解决方案是,“好吧,不要犯任何错误”?!保证没有错误的唯一方法是什么都不做。我们都会犯错误,需要找到方法将安全性设计到流程中。
-
@MikeWilliamson:另见here。所以“如果我们使用
void不是更好吗?”也可以回答为“有更简单的方法可以达到相同的目标”。
标签: javascript iife