JS模块化初步实现过程
当我们在html中调用一个js函数时,如果我们把这个函数写在另外的一个js文件中,那么调用的时候我们需要在html的头部引入那个js文件。<!-- more -->
index.html
<head> <script type="text/javascript" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="index.js"></script> </head> <body> <h1 id="boy">Hello world</h1> <input type="button" onclick="Girl()" value="click"> </body> </html>
index.js
function Girl(){ var p = document.getElementById("boy"); p.innerHTML = "I am a boy"; }
此时,若我们需要在index.js中生成的文字是动态的,且由另一个js(matn.js)产生,那么如果在java中可以在index.js中使用import package+class模式引用另一个文件中的方法,但是对于javascript这种动态的语言来说是不可以的。因此如果我们要在index.js中能够调用math.js中的函数,那么我们需要同时在index.html中引入math.js。
index.html<head> <script type="text/javascript" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="index.js"></script> <script type="text/javascript" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="math.js"></script> </head> <body> <h1 id="boy">Hello world</h1> <input type="button" onclick="Girl()" value="click"> </body> </html>
>index.js
//import "math.js" 不支持这种写法
function Girl(){
var p = document.getElementById("boy");
p.innerHTML = add(1,2);
}
>math.js
function add(a,b){
return a + b;
}
我们可以看到这种写法并不优雅,index.js对于math.js没有控制权,能不能调用到add()函数完全取决于自己的html有没有正确的引入math.js。
所以这边就产生了两个问题:
1.index.js无法import,依赖html的引用
2.index.js中无法对add方法的来源做区别分,缺少命名空间的概念
#初步模块化
解决第二个问题,也就是命名空间的概念。
我们把math中的函数放进去一个以math命名的对象中,这样就形成了一个简易版的命名空间了。
>math.js
var math = {
base: 5,
add: function(a,b){
return a + b;
},
};
>index.js
function Girl(){
var p = document.getElementById("boy");
p.innerHTML = math.add(1,2);//我们知道了这个方法来自math这个文件
}
但是这里math对象中的另一个属性base也会被暴露和修改,因此我们升级一下。
>math.js
var math = (function(){
var base = 7;
return {
add: function(a,b){
return a + b + base;
},
};
})();
我们把math定义在一个闭包中,从而隐藏了内部属性。
index.js
function Girl(){
var p = document.getElementById("boy");
p.innerHTML = math.add(1,2);
document.write(math.base);//undefine
}
到目前为止,我们完成了模块的简易定义与使用。但是模块化的一大精髓是命名空间,就是按需导入,而此时math却是一个全局变量。因此我们可以引入中间件来解决这个问题。
#引入中间件
我们定义一个全局变量
>global.js
var module = {
export: {}
}
在math.js中
var math = (function(){
var base = 7;
return {
add: function(a,b){
return a + b + base;
},
};
})();
mmodule.export.math = math;//把math注册
>index.js
var math = module.export.math;//指定了math.js中的math方法
function Girl(){
var p = document.getElementById("boy");
p.innerHTML = math.add(1,2);
}
共同学习,写下你的评论
评论加载中...
作者其他优质文章