对于模块模式,我正在做类似的事情:
(function(namespace) {
// tons of code
// blabla
})(window.myGlobalNamespace);
如何拆分代码?我可以想到几种方法,例如使用命名空间的层次结构,或者通过以下方式将对象扩展到外部window.myGlobalNamespace.additionalFunc = function () {//blabla}
。还有哪些其他方法?优缺点都有什么?哪一种被认为是更好的做法?
这两个答案都建议使用 RequireJS。您能否解释一下 RequireJS 如何解决这些问题:
首先.js:
(function(context) {
var parentPrivate = 'parentPrivate';
})(window.myGlobalNamespace);
第二个.js:
(function(context) {
this.childFunction = console.log('trying to access parent private field: ' + parentPriavte);
}(window.myGlobalNamespace.subNamspace);
main.js:
window.myGlobalNamespace.subNamspace.childFunction(); // doesn't work
人们可以做到
window.myGlobalNamespace.subNamspace.childFunction = function() {alert("a new function");}
改变我的代码的行为!
这里,有两个问题:
我们不能有一个儿童可以访问但外部公众不能访问的字段(即受保护的字段)。有什么办法可以实现这一点吗?
如果不是,这意味着如果我们希望可以访问parentPrivate,我们需要将其公开。然后用户就可以修改它了!
更重要的是,所有的公共职能都可以改变和替换。我不希望这种事发生。
我不明白 RequireJS 如何解决这些问题。有人可以透露一些信息吗?
将 JavaScript 转换为 HTML 只有两种方法:
-
Inline -
<script> some JavaScript </script>
-
Link -
<script src='main.js'></script>
我知道这是显而易见的,但我们需要为接下来的事情找到共同点。 ;)
JavaScript 没有能力将其他 JavaScript 文件“导入”到它自身中。所有“导入”都是在 HTML 中完成的。您可以通过多种方式执行此操作:
-
Link每一项都单独放入 HTML 中
-
动态链接他们通过一些JavaScript
var script = document.createElement("script");
script.src = "all.js";
document.documentElement.firstChild.appendChild(script);
Library like 要求JS。 RequireJS 使用异步模块定义 (AMD) API。它是用于定义模块的 JavaScript 机制,以便可以异步加载模块及其依赖项。
考虑将 JavaScript 分成单独文件的原因很重要。
-
可维护性- 一次处理一件作品变得更加容易
-
可读性- 如果所有内容都在一个大文件中,则很难看出什么是什么
-
分工- 让多个开发人员处理多个文件比处理一个大文件更容易
-
Reuse- 您的所有功能都可以分解为高度凝聚力模块
单独的 JavaScript 文件DO NOT做东西Private,闭包使事情变得私有。
现在,考虑一下在一天结束时,当一切都准备好进行生产时,您能做的最好的事情是Optimize您可以将 JavaScript 全部合并到一个文件中,以便用户只需下载一个文件。
在 JavaScript 中处理私有变量时,您有时会想要访问它们。
-
Public功能 - 可以altered.
-
特权函数-aPublic可以访问的函数Private多变的。
- 但是,如果该函数位于Instance那么它就可以只能在每个对象中更改.
让我用一些代码来说明。
module-test.html 和 main.js (合并了first.js、second.js 和main.js 以方便测试)
var MODULE = (function () {
//Private variables
var privateParent,
app;
privateParent = 'parentPrivate';
return app = {
//Privileged method
getPrivateParent: function() {
return privateParent;
}
};
}());
MODULE.sub = (function (parentApp) {
//Private variables
var childMessage,
Constr;
childMessage = ' - trying to access parent private field: ' + parentApp.getPrivateParent(); //prints parentPrivate
Constr = function () {
this.childF = this.childFunction();
};
//Constructor
Constr.prototype = {
constructor: MODULE.sub,
version: "1.0",
childFunction: function () {
$("#testing-div").append(childMessage + "</br>");
}
};
return Constr;
}(MODULE));
//We could just as easily print to the console, but the 'append' allows us to display the results on the page.
$("#testing-div").append("This first part shows what <b>does not work</b>; everything is 'undefined'. " + "</br>");
$("#testing-div").append("You are unable to access the var or func directly. " + "</br>");
$("#testing-div").append("MODULE.privateParent = " + MODULE.privateParent + "</br>");
$("#testing-div").append("MODULE.app = " + MODULE.app + "</br>");
$("#testing-div").append("MODULE.sub.childMessage = " + MODULE.sub.childMessage + "</br>");
$("#testing-div").append("MODULE.sub.Constr = " + MODULE.sub.Constr + "</br>");
$("#testing-div").append("MODULE.sub.childFunction = " + MODULE.sub.childFunction + "</br>");
$("#testing-div").append("END lesson. You must access childFunction() through the <b>new</b> operator." + "</br>");
$("#testing-div").append("----------------------------------------------------" + "</br>");
$("#testing-div").append("Let's see if making an instance of the Object works" + "</br>");
var test = new MODULE.sub();
test.childFunction(); //run the method
$("#testing-div").append("Looks like it did!!!!" + "</br>");
$("#testing-div").append("----------------------------------------------------" + "</br>");
$("#testing-div").append("Now let's try to change the childFunction() ?" + "</br>");
test.childFunction = function() {$("#testing-div").append(" - This is a new function." + "</br>");}
test.childFunction(); // altered version
$("#testing-div").append("Looks like it was changed. :(" + "</br>");
$("#testing-div").append("----------------------------------------------------" + "</br>");
$("#testing-div").append("Does it stay changed?" + "</br>");
var test2 = new MODULE.sub();
test2.childFunction(); // doesn't work
$("#testing-div").append("NO, it was only Overriden in the 'test' Object. It did not effect all the other new objects. :)" + "</br>");
$("#testing-div").append("----------------------------------------------------" + "</br>");
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Module Test</title>
<!-- <script data-main="scripts/main" src="scripts/require.js"></script> -->
</head>
<body>
<h1>This is a test for separate Modules and Private variables.</h1>
<div id="testing-div">
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="main.js"></script>
</body>
</html>
---
如果您想使用 RequireJS 来完成上述任务,也可以。 RequireJS 使用你我已经在使用的模块模式。如果您想分离文件,有两种方法可以实现。
-
Normal- 只需设置您的 JS 文件以使用 RequireJS,然后只需稍作修改即可放入上述模块。
-
杠杆化- 使用 RequireJS 的模块性质作为设置闭包的模块。这看起来可能更难弄清楚,但从长远来看可能更有效。
NOTE: 我还没有机会比较这两个选项,但为了完整起见,我想将它们包括在内。
您可能会发现以下参考资料很有帮助:
- JavaScript 模块模式:深入
- JavaScript 中的私有成员
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)