Hello Stackoverflow人员,
问题是代码风格和代码可维护性,而不是搜索某些错误。
我们假设我正在为node.js创建一些模块。这个模块只导出一个对象,让我们调用这个对象" FileParser"。在文件解析期间,可以有不同的预处理功能。它们非常独特,我不打算在应用程序的其他部分重用它们。
因为,这个模块只导出一个函数 - 我的问题是下一个:
如果我有这个模块的一些实用函数,我应该在导出的函数中定义这个函数,还是应该在这个函数之外定义它们。
基本上 - 这个:
var FileParser = function(){
}
FileParser.prototype.methodToExport = function(){
var utilityFunction = function(){
//do some work, maybe even return values
}
//do some other work.
utilityFunction();
//do more other work
}
module.exports.FileParser = FileParser;
或者这个:
var FileParser = function(){
}
FileParser.prototype.methodToExport = function(){
//do some work before calling function
utilityFunction();
//do more and more work after calling function
}
function utilityFunction(){
//body of function goes here, maybe even returning some value
}
module.exports.FileParser = FileParser;
更具可读性,特别是在实用功能很少的情况下。
谢谢, -D
答案 0 :(得分:4)
如果utilityFunction
未用作闭包(即它不访问methodToExport
函数中声明的变量),则没有充分的理由在其他函数内声明它。
把它放在外面,它会使methodToExport
缩短(因此更具可读性)。
由于它位于“本地”模块范围内,因此您甚至无需担心全局命名空间污染。如果实用程序功能的数量增加,您可以考虑对它们进行适当的分组,例如通过使用揭示模块模式。
答案 1 :(得分:0)
在第一种情况下,每次调用methodToExport
时都会声明您的函数,在第二种情况下,您将具有全局函数。也许你可以使用某种封闭:
FileParser.prototype.methodToExport = function() {
function utilityFunction () {
//do some work, maybe even return values
}
return function () { // This is the real function, the one which will be export!
//do some other work
utilityFunction () ;
//do more other work
} ;
} () ;
也许有更好的方法,但我会做那样的事情!
答案 2 :(得分:0)
JavaScript足够灵活,可以允许这样的事情,声明如下,但在我看来并不是一个好的实践。
var FileParser = function(){
}
FileParser.prototype.methodToExport = function(){
var utilityFunction = function(){
//do some work
}
utilityFunction();
}
module.exports.FileParser = FileParser;
您正在声明并调用函数内部,但更明确的是在FileParser对象的声明中执行此操作。
所以,你有很好的宣传模式Revealing Pattern,由Addy Osmani提出。
var FileParser = function(){
var utilityOne = function(){
}
this.methodToExport = function(){
// do some work
utilityOne();
}
}
module.exports.FileParser = FileParser;
这可以隐藏一些实用功能作为一种封装,只显示外面的重要功能。
答案 3 :(得分:0)
你没有问过这个问题,但是我建议你把你的代码放在IIFE里面,这样在顶级闭包中只有一个变量,如下所示:
module.exports.FileParser = (function(){
var FileParser = function(){};
// Do your stuff
return FileParser;
})();
这样可以节省为FileParser创建全局变量的需要。
现在关于你问过的问题 - 如果在导出的函数中或在其外部定义效用函数 - 我的答案取决于你是仅导出单个函数还是多个函数。在你的情况下,因为你只导出一个函数,我的答案是,只要你有一个选择,我更喜欢外部定义的效用函数,因为它的闭包范围更小。 “只要你有选择权”,我的意思是你的效用函数没有使用methodToExport
中定义的任何东西。
module.exports.FileParser = (function(){
var FileParser = function(){};
var utilityOne = function(){};
FileParser.prototype.methodToExport = function(){
// do some work
utilityOne();
}
return FileParser;
})();
较小的闭合范围在大多数情况下并没有太大的区别,但以下是一个例子。
module.exports.FileParser = (function(){
var FileParser = function(){};
FileParser.prototype.methodToExport = function(){
var longArray = [ /* ... */ ];
var utilityOne = function(){
setInterval(function(){
console.log("Hello");
},1000);
};
utilityOne();
}
return FileParser;
})();
在上面的示例中,longArray
位于utilityOne()
的封闭中,即使不需要它。 setTimeout对longArray
的引用可以防止它被垃圾回收。
module.exports.FileParser = (function(){
var FileParser = function(){};
var utilityOne = function(){
setInterval(function(){
console.log("Hello");
},1000);
};
FileParser.prototype.methodToExport = function(){
var longArray = [ /* ... */ ];
utilityOne();
}
return FileParser;
})();
将utilityOne()
定义移出方法定义会缩小其闭包范围,并允许对longArray
进行垃圾回收。