只有两种方法可以将JavaScript引入HTML:
- 内联 -
<script> 某些JavaScript </script>
- 链接 -
<script src='main.js'></script>
我知道这很明显,但我们需要这个共同的基础来进行下一步。 ;)
JavaScript没有能力将其他JavaScript文件"导入"到自己中。所有的"导入"都在HTML中完成。你可以用几种方式做到这一点:
- Link each one individually into the HMTL
Dynamically link them in through some JavaScript
var script = document.createElement("script")
script.src = "all.js"
document.documentElement.firstChild.appendChild(script)
Library like RequireJS. RequireJS uses Asynchronous Module Definition (AMD) API. It is the JavaScript mechanism for defining modules such that the module and its dependencies can be asynchronously loaded.
考虑把JavaScript分成单独的文件有以下几个原因:
- 可维护性 - 每次只需要处理一个部分会更容易
- 可读性 - 如果所有内容都在一个大文件中,很难看清楚哪个是哪个
- 分工合作 - 多个开发人员可以在多个文件上工作,而不是只在一个大文件上工作
- 重用 - 所有函数都可以拆分为高内聚模块
将JavaScript文件分开不会使事情变得私有,闭包使事情变得私有。
现在,考虑到最后一天当一切准备好进入生产时,最好的做法是通过将所有内容组合成一个文件来优化您的JavaScript,这样用户只需下载一个文件即可。
处理JavaScript中的私有变量时,您最终需要访问它们。
- 公共函数 - 可以更改。
- 特权函数 - 可以访问私有变量的公共函数。
- 但是,如果该函数在实例中,则只能在每个对象中进行更改。
让我用一些代码来说明。
module-test.html and main.js (merged first.js, second.js, and main.js for easier testing)
var MODULE = (function () {
var privateParent,
app;
privateParent = 'parentPrivate';
return app = {
getPrivateParent: function() {
return privateParent;
}
};
}());
MODULE.sub = (function (parentApp) {
var childMessage,
Constr;
childMessage = ' - trying to access parent private field: ' + parentApp.getPrivateParent();
Constr = function () {
this.childF = this.childFunction();
};
Constr.prototype = {
constructor: MODULE.sub,
version: "1.0",
childFunction: function () {
$("#testing-div").append(childMessage + "</br>");
}
};
return Constr;
}(MODULE));
$("#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();
$("#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();
$("#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();
$("#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>
</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使用的是模块模式,这也是我们已经在使用的。如果你想将文件分离出来,有两种方法可以实现。
1. 普通方式 - 只需设置你的JS文件使用RequireJS并稍微修改上面的模块即可。
2. 利用方式 - 使用RequireJS的模块特性来设置闭包。这看起来可能更难理解,但从长远来看可能更有效。
注意:我还没有比较这两个选项,但为了完整性起见,我想把它们都包括进来。
您可能会发现以下参考资料有帮助:
myFunction
函数。但是,如果我将myFunction
设置为公共函数,那么客户端是否也可以通过window.B.myFunction = ...
来修改该函数呢?我该如何解决这个问题?假设myFunction
不应被修改且其非常关键。 - Boyang