JavaScript 连接器
我正在考虑编写一个 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)。这里完全相同的问题,所以我相信这是一个真正的问题。
提出的解决方案——JS Concatenator
将它们放在一个封闭的地方,在飞行中。
这就是我想象的应该如何工作。在 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'};
这行得通吗?
这个提议的解决方案会起作用吗?我错过了一些重要的观点吗?什么是潜在的问题?我该如何实施呢?任何建议都非常感谢!