详谈JavaScript的模块化开发

到底什么是模块化?

如今backbone、emberjs、spinejs、batmanjs 等MVC框架侵袭而来。CommonJS、AMD、NodeJS、RequireJS、SeaJS、curljs等模块化的JavaScript扑面而来。web前端已经演变成大前端,web前端的发展速度之快。
模块化是一种将系统分离成独立功能部分的方法,可将系统分割成独立的功能部分,严格定义模块接口、模块间具有透明性。javascript中的模块在一些C、PHP、java中比较常见:

  • c中使用include 包含.h文件;
  • php中使用require_once包含.php文件
  • java使用import导入包

模块化的优缺点

优点:

可维护性
1.灵活架构,焦点分离
2.方便模块间组合、分解
3.方便单个模块功能调试、升级
4.多人协作互不干扰
可测试性
1.可分单元测试

缺点:

性能损耗
1.系统分层,调用链会很长
2.模块间通信,模块间发送消息会很耗性能

引用模块的几种方式

模块模式
1.匿名闭包函数

(function () {
    //下面的变量是私有的
    var name="xwk";
    var age="23";
    var say=function () {
        return name+"的年龄是"+age;
    };
    console.log(say())
}());

通过这种构造,匿名函数形成了闭包,使得父作用域即全局里面访问不到里面的变量,好处是隔离了全局中的变量,不会出现同名污染
2.全局引入
与上面所介绍的匿名闭包函数差不多,只不过,将全局变量以参数的形式传入到函数中,jquery的封装就是如此

(function(globalVariable){
              ...    
                  }
(globalVariable))

3.对象接口

var globalObj=(function () {
    return {
        func1:function () {
            return "r1";
        },
        func2:function () {
            return "r2";
        }
    }
})();
console.log(globalObj.func1())

commonJS & AMD模式

1.commonJs

CommonJS模块可以很方便得将某个对象导出,让他们能够被其他模块通过 require 语句来引入。要是你写过 Node.js 应该很熟悉这些语法。

通过CommonJS,每个JS文件独立地存储它模块的内容(就像一个被括起来的闭包一样)。在这种作用域中,我们通过 module.exports 语句来导出对象为模块,再通过 require 语句来引入。

function module1() {
    this.name=function () {
        return "xwk";
    };
    this.age=function () {
        return "23";
    }
}
module.exports = module1;

如果想要引用时,只需要require一下

var m1=require("module1");
var module1=new m1();
module1.name();
module1.age();

这种实现比起模块模式有两点好处:

  1. 避免全局命名空间污染
  2. 明确代码之间的依赖关系

注意!!!
使用commonJs模式,是以服务器优先的模式来同步加载模块,假如我们加载3个模块,这3个模块将一个个的依次载入,缺点就是对浏览器端不太友好,只要他还在加载模块,页面就会一直卡着不动直到模块加载完成。

2.AMD模式

CommonJS已经挺不错了,但假使我们想要实现异步加载模块该怎么办?答案就是Asynchronous Module Definition(异步模块定义规范),简称AMD.

通过AMD载入模块的代码一般这么写:

define(["module1","module2"],function(module1,module2){
   console.log(module.hello())
});
//define方法,第一个参数是与之依赖的模块数组(注意是数组,如果没有,用[]表示),第二个参数是一个模块加载完成的回调函数,回调函数的参数是我们引入的模块

这些模块本身也需要用define声明,例如module1模块:

define([],function(){
      return {
        func1:function () {
            return "r1";
        },
        func2:function () {
            return "r2";
        }
    }
 });

除了异步加载以外,AMD的另一个优点是你可以在模块里使用对象、函数、构造函数、字符串、JSON或者别的数据类型,而CommonJS只支持对象。

3.UMD模式

UMD创造了一种同时使用两种规范的方法,并且也支持全局变量定义。所以UMD的模块可以同时在客户端和服务端使用。由于我也没用过,这里将不在详细介绍。。。。

RequireJs框架

RequireJS是一个非常小巧的JavaScript模块载入框架,是AMD规范最好的实现者之一。

基本api
equire会定义三个变量:define,require,requirejs,其中require === requirejs,一般使用require更简短。

  • define 从名字就可以看出这个api是用来定义一个模块
  • require 加载依赖模块,并执行加载完后的回调函数

明天继续更。。

你可能感兴趣的:(详谈JavaScript的模块化开发)