javascript模块化开发编程

随着网站的不断迭代更新,js代码越来越多,那么问题来了

  • 代码比较乱

  • 命名出现冲突

  • 文件依赖比较繁杂

为了解决以上问题,模块化开发出现了

1、一个简单的demo,维护和扩展模块

模块的维护和扩展一定要遵守一个约定:开闭原则

对添加开放,对修改封闭

<!DOCTYPE html>
<html >

<head>
  <meta charset="UTF-8">
  <title>扩展和维护模块</title>
</head>

<body>
  <div>
    <input type="text" >
    <select name="" >
      <option value="0"> + </option>
      <option value="1"> - </option>
      <option value="2"> * </option>
      <option value="3"> / </option>
      <option value="4"> % </option>
    </select>
    <input type="text" >
    <input type="button" >
    <input type="text" >
  </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 >

<head>
  <meta charset="UTF-8">
  <title>第三方包依赖的问题</title>
</head>

<body>
  <div>
    <input type="text" >
    <select name="" >
      <option value="0"> + </option>
      <option value="1"> - </option>
      <option value="2"> * </option>
      <option value="3"> / </option>
      <option value="4"> % </option>
    </select>
    <input type="text" >
    <input type="button" >
    <input type="text" >
  </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