随着网站的不断迭代更新,js代码越来越多,那么问题来了
-
代码比较乱
-
命名出现冲突
-
文件依赖比较繁杂
为了解决以上问题,模块化开发出现了
1、一个简单的demo,维护和扩展模块
模块的维护和扩展一定要遵守一个约定:开闭原则
对添加开放,对修改封闭
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>扩展和维护模块</title> </head> <body> <div> <input type="text" id="x"> <select name="" id="opt"> <option value="0"> + </option> <option value="1"> - </option> <option value="2"> * </option> <option value="3"> / </option> <option value="4"> % </option> </select> <input type="text" id="y"> <input type="button" id="btn" value="="> <input type="text" id="result"> </div> <script> /** * 通过 匿名自执行函数,利用函数作用域的机制 隔离私有变量 */ var calculator = (function() { // 对于 _count 来说,如果不通过 return ,外部是无法访问的,无法修改 var _count = 10; function add(x, y) { return parseFloat(x) + parseFloat(y); }; function substract(x, y) { return parseFloat(x) - parseFloat(y); }; function multiply(x, y) { return parseFloat(x) * parseFloat(y); }; function divide(x, y) { return parseFloat(x) / parseFloat(y); }; return { add: add, substract: substract, multiply: multiply, divide: divide }; })(); var calculator = (function(cal) { cal.mod = function(x, y) { return x % y; }; return cal; })(window.calculator || {}); // 看一下 全局有没有 calculator 该对象,如果有,直接使用该对象就可以了 // 如果没有,给一个默认的空对象,一种更 鲁棒 的做法,更高的容错性,永远不要相信用户的输入 var oX = document.getElementById('x'); var oY = document.getElementById('y'); var oOpt = document.getElementById('opt'); var oBtn = document.getElementById('btn'); var oResult = document.getElementById('result'); oBtn.addEventListener('click', function(e) { var x = oX.value.trim(); var y = oY.value.trim(); var opt = oOpt.value; var result = 0; switch (opt) { case '0': result = calculator.add(x, y); break; case '1': result = calculator.substract(x, y); break; case '2': result = calculator.multiply(x, y); break; case '3': result = calculator.divide(x, y); break; case '4': result = calculator.mod(x, y); break; } oResult.value = result; }); </script> </body> </html>
2、第三方包依赖的解决
不要直接在模块内部使用第三方依赖,因为模块与模块之间的依赖关系不够明显,最好通过将依赖项注入的形式来解决第三方依赖的问题
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>第三方包依赖的问题</title> </head> <body> <div> <input type="text" id="x"> <select name="" id="opt"> <option value="0"> + </option> <option value="1"> - </option> <option value="2"> * </option> <option value="3"> / </option> <option value="4"> % </option> </select> <input type="text" id="y"> <input type="button" id="btn" value="="> <input type="text" id="result"> </div> <!-- 模块依赖的问题 1. 手动方式加载:不方便 2. 模块的加载顺序:可能会出错 --> <script src="../js/jquery-1.11.3.js"></script> <script> /** * 通过 匿名自调用函数,利用函数作用域的机制隔离私有变量 */ var calculator = (function() { // 对于 _count 来说,如果不通过 return ,外部是无法访问的,无法修改 var _count = 10; function add(x, y) { return parseFloat(x) + parseFloat(y); }; function substract(x, y) { return parseFloat(x) - parseFloat(y); }; function multiply(x, y) { return parseFloat(x) * parseFloat(y); }; function divide(x, y) { return parseFloat(x) / parseFloat(y); }; return { add: add, substract: substract, multiply: multiply, divide: divide }; })(); var calculator = (function(cal,$) { cal.changeColor = function() { $('#x').css('backgroundColor', 'red'); $('#y').css('backgroundColor', 'green'); }; return cal; // 不要直接用$或其他第三方包,一定要把依赖项 通过参数的形式 注入进来,然后在内部使用注入的属性 // 好处: // 1. 依赖关系变的明显,有利于代码的阅读 // 2. 提高了性能:减少了作用域的查找范围 })(window.calculator || {}, window.$); var oX = document.getElementById('x'); var oY = document.getElementById('y'); var oOpt = document.getElementById('opt'); var oBtn = document.getElementById('btn'); var oResult = document.getElementById('result'); oBtn.addEventListener('click', function(e) { calculator.changeColor(); var x = oX.value.trim(); var y = oY.value.trim(); var opt = oOpt.value; var result = 0; switch (opt) { case '0': result = calculator.add(x, y); break; case '1': result = calculator.substract(x, y); break; case '2': result = calculator.multiply(x, y); break; case '3': result = calculator.divide(x, y); break; case '4': result = calculator.mod(x, y); break; } oResult.value = result; }); </script> </body> </html>
模块化开发的总结:
最大的问题,即规范问题,尤其在多人协作开发过程中,因此在多人协作开发过程中,一定要注意代码风格的统一。
为了解决模块化规范问题,出现了第三方库,基于AMD规范的Require.js和基于CMD规范的Sea.js,具体使用方法,参考其文档,至于AMD和CMD规范的区别可以参考以下博客
http://www.cnblogs.com/dojo-lzz/p/4707725.html
http://blog.chinaunix.net/uid-26672038-id-4112229.html