我正在考虑编写一个JavaScript库来实现模块化下的数据隐藏。我希望得到一些关于这是否有用以及潜在问题的一些意见。
让我先解释一下这个问题。我想要实现的是:
数据隐藏的含义是这种模式:
!function(context) {
var privateObj = {state: 'normal'};
var privateFunc = function() {alert("I'm private")};
var toggleState = function() {privateObj.state = 'emergency'};
}(window.myNamespace);
在这里,好奇的用户将无法更改我的私有变量,也无法调用我的私有函数。
只要一切都在一个js文件中,上面的工作就可以了。但是,一旦js文件变得太大,我想模块化:
first.js:
!function(context) {
var privateObj = {state: 'normal'};
var privateFunc = function() {alert("I'm private")};
}(window.myNamespace);
second.js:
!function(context) {
// This won't work. I can't access privateObj as we are not in same closure
var toggleState = function() {privateObj.state = 'emergency'};
}(window.myNamespace2);
它将不再起作用。当然,我可以将toggleState
与privateObj
放在一起,但总是需要跨模块传递数据。这只是一个例子。
我们是否希望其他模块可以访问某个功能但公众无法访问?我想是的。一个直截了当的例子就是:
var chartDrawingMod = function() {
var drawChart = function(data) {// draw chart with data};
};
在这种情况下,我们都应该同意
图表相关的东西本身应该是内聚模块
方法drawChart()应该由我在其他模块中的代码调用来提供数据
我们不希望用户习惯性地调用我的drawChart()因此不希望公开它
MathJax项目遇到此问题。他们的解决方案是使用bash脚本在部署之前连接所有脚本。他们需要这样做的原因是,首先模块是相互依赖的,因此它们需要位于同一个文件中,其次,如果组合(30k LOC),文件太大而无法管理。这里的问题完全相同,所以我认为这是一个真正的问题。
将它们放在一个闭包中,即时。
以下是我认为应该如何运作的方式。在HTML中我有这些:
<script src="concatenator.js"></script>
<script>
Concat.concateIntoOneClosureWithContext(['/public/js/first.js', '/public/js/second.js'], window.myNamespace);
</script>
然后它应该做这样的事情:
!function(context) {
// dump the content of '/public/js/first.js'
// dump the content of '/public/js/second.js'
}(window.myNamespace);
first.js
和second.js
被删除为:
var privateObj = {state: 'normal'};
var privateFunc = function() {alert("I'm private")};
var toggleState = function() {privateObj.state = 'emergency'};
这个提议的解决方案是否有效?我错过了一些重点吗?有什么潜在的问题?我该如何实施呢?任何建议都非常感谢!