我一直在nodejs中编写模块,如下所示:
module.exports = function (logger, db, external,constants) {
return {
//something
}
}
最近,我的团队中有人建议将整个脚本包装在一个函数中,以避免变量的全局混淆,即:
(function () {
'use strict';
module.exports = function (logger, db, external,constants) {
return {
//something
}
}
}());
我知道这种做法通常用于客户端代码。但是在nodejs的服务器端需要吗?我认为在nodejs中实际上没有全局范围,只有module.exports是无论我们在脚本文件中编写什么都可以访问的(当然不要在这里疯狂(。
不,Node.js不需要 IIFE。
它们对于可能在多个环境 (UMD( 中使用的任何脚本都很有用。
但是,Node.js执行的每个模块/文件都被赋予了一个"模块范围",类似于IIFE提供的范围,如"全局"中所述:
在浏览器中,顶级作用域是全局作用域。这意味着在浏览器中,如果您在全局范围内,
var something
将定义一个全局变量。在 Node 中,这是不同的。顶级作用域不是全局作用域; 节点模块内部var something
将是该模块的本地。
不过,Node.js 仍然有一个全局范围。当模块创建全局时,它将在同一进程使用的其他模块中访问。
foo = 'bar'; // lack of `var` defines a global
console.log(global.foo); // 'bar'
你实际上已经在这样做了。
他的建议是将整个脚本包装在这样的函数中:
function () {
}
就这样。没什么特别的。当然,在常规 javascript 中,函数定义只定义一个函数,函数中的代码不会运行。因此,要自动运行函数,请将其包装在表达式上下文中并调用它:
(function () {
})()
但是,在节点中.js您不需要执行此操作。相反,您可以在需要模块时简单地调用该函数。因此,在node.js中,这在创建私有作用域方面执行完全相同的操作:
module.exports = function () {
}
因此,请告诉您的朋友,您已经将整个脚本包装在一个函数中。
这可能是我看到命名事物和设计模式的危害的第一个案例。在这种情况下,您的朋友正在考虑IIFE。但IIFE并没有什么特别之处。IIFE 不会创建专用范围。创建范围的函数。IIFE 只是函数调用自身的一种手段。这就是为什么我更喜欢称它为自召函数,以避免给它一种魔力感,这可能会导致一些人认为它是特别的东西。