隨着網站開發的複雜度越來越高,js代碼和js文件的增多,出現了開發者頭疼的兩個問題:① 命名衝突;②文件依賴。
js模塊化開發可以解決這些問題。
①變量命令衝突
在js文件中,如下創建一個變量並賦予一個函數。如果文件的代碼過多,在後續的代碼中再次使用add變量,就會將原來的add變量覆蓋,就造成了變量的命名衝突。
var add=function(v1,v2){
return v1+v2;
}
// 此處省略一萬行代碼
var add = 123;
我們逐漸試着重代碼進行改善
(1)對象封裝
var calculator={
num:123;
}
calculator.add=function(v1,v2){
return v1+v2;
}
這時候 add的作用範圍在caculator對象中,就不會避免後續代碼直接寫 var add = value 造成變量命名衝入。但是這樣的代碼還是有很大的侷限性,對象裏面的屬性和方法很容易被修改掉,很不安全。
(2)劃分私有命名空間
var calculator=(function(){
var num=123;
var add=function(v1,v2){
return v1+v2;
};
return {
num:num,
add:add
}
})()
通過匿名函數,閉包將add的私有化到calculator中,可以保護好裏面的屬性和方法,但是這種方式的侷限在於不能維護和擴展功能。
(3)開閉原則-維護擴展
var calculator=(function(){
var num=123;
var add=function(v1,v2){
return v1+v2;
};
return {
num:num,
add:add
}
})();
var calculator=(function(global){
global.mod=function(v1,v2){
return v1%v2;
}
return global;
})(window.calculator||{});
對add的修改關閉了,同時提供了對calculator的功能擴展,window.caucluator傳遞就是爲了打破封裝性。
②文件依賴
在開發js代碼的過程中,例如使用了jquery.js,就需要通過<script src="./jquery.js"></script>的形式引入文件,形成硬編碼。如以下代碼
var calculator=(function(){
var num=123;
var add=function(v1,v2){
return v1+v2;
};
return {
num:num,
add:add
}
})();
var calculator=(function(global){
global.mod=function(v1,v2){
return $(v1) % $(v2); // 這裏使用了jquery的$
}
return global;
})(window.calculator||{});
根據以上問題,引入模塊化開發
模塊化規範
①服務器端規範
nodejs就是遵循了CommonJS規範。
②瀏覽器端規範
RequireJS遵循AMD規範。
SeaJS遵循CMD規範。
這裏先介紹SeaJS Demo
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>SeaJS Demo</title>
<script type="text/javascript" src="./modules/seajs/2.2.0/sea.js"></script>
</head>
<body>
<input type="" name="" value="1" id="v1">
<input type="" name="" value="2" id="v2">
</body>
<script type="text/javascript">
seajs.use('./modules/calculator',function(cal){ // 參數1:引入模塊路徑;參數2:回調函數
console.log(cal.add2());
});
</script>
</html>
在index.js的同級目錄modules中,創建如下文件
calculator.js
define(function(require,exports,module) {
var operator = require('./add');
exports.add=operator.add;
exports.add2=operator.add2;
});
add.js
define(function(require,exports,module) {
var add=function(v1,v2){
return v1+v2;
}
$=require('./jquery.js');
var add2=function(){
var v1= $('#v1').val();
var v2= $('#v2').val();
return (v1-0)+(v2-0);
}
exports.add=add;
exports.add2=add2;
});
文件目錄
(1)define是SeaJS的全局函數,定義模塊。
(2)modules是一個全局變量相當於 瀏覽器解析dom 的window對象。
(3)exports是modules.exports的屬性對象別名;不能直接給exports賦值,暴露單個屬性和方法直接給module.exports賦值。exports提供多個屬性和方法向外暴露。
(4)seajs.user()函數啓動模塊;
(5)require() 用於加載模塊。
模塊化開發保證了複合“單一職責”設計,通過匿名函數的注入,保證了模塊的獨立性,而且也能清晰的表達模塊之間的依賴。這裏簡單介紹SeaJS,如果需要知道更多,訪問http://www.zhangxinxu.com/sp/seajs/