手记

JS模块化初步实现过程

为什么需要模块化?

当我们在html中调用一个js函数时,如果我们把这个函数写在另外的一个js文件中,那么调用的时候我们需要在html的头部引入那个js文件。<!-- more -->

index.html

<head>
<script type="text/javascript" src="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" src="index.js"></script>
<script type="text/javascript" src="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);
}

1人推荐
随时随地看视频
慕课网APP