JavaScript之模块化

1、原始写法

  function m1(){
    //...
  }
  function m2(){
    //...
  }

这种做法的缺点很明显:"污染"了全局变量,无法保证不与其他模块发生变量名冲突,而且模块成员之间看不出直接关系。

2、对象写法

var module1 = new Object({

    _count : 0,

    m1 : function (){
      //...
    },

    m2 : function (){
      //...
    }

  });

上面的函数都封装在module里可通过module1.m1();访问,但是,这样的写法会暴露所有模块成员,内部状态可以被外部改写module1._count = 5;

3、立即执行函数写法

var module1 = (function(){
    var _count = 0;
    var m1 = function(){
      //...
    };
    var m2 = function(){
      //...
    };
    return {
      m1 : m1,
      m2 : m2
    };
  })();

这样写外部代码无法读取内部的_count变量。
这种写法就是Javascript模块的基本写法。下面,再对这种写法进行加工。

4、放大模式

如果一个模块很大,必须分成几个部分,或者一个模块需要继承另一个模块,这时就有必要采用"放大模式"(augmentation)。

var module1 = (function (mod){
    mod.m3 = function () {
      //...
    };
    return mod;
  })(module1);

上面的代码为module1模块添加了一个新方法m3(),然后返回新的module1模块。

5、宽放大模式(Loose augmentation)

在浏览器环境中,模块的各个部分通常都是从网上获取的,有时无法知道哪个部分会先加载。如果采用上一节的写法,第一个执行的部分有可能加载一个不存在空对象,这时就要采用"宽放大模式"。

var module1 = ( function (mod){
    //...
    return mod;
  })(window.module1 || {});

输入全局变量

var module1 = (function ($, YAHOO) {
    //...
  })(jQuery, YAHOO);

6、模块化规范

1、CommonJS规范(同步加载模块)主要用于服务端

// 导入
require("module");
require("../app.js");
// 导出
exports.getStoreInfo = function() {};
module.exports = someValue;
  • 优点:
    简单容易使用
    服务器端模块便于复用
  • 缺点:
    同步加载方式不适合在浏览器环境中使用,同步意味着阻塞加载,浏览器资源是异步加载的
    不能非阻塞的并行加载多个模块

参照CommonJs模块代表node.js的模块系统
2、AMD(异步加载模块)

// 定义
define("module", ["dep1", "dep2"], function(d1, d2) {...});
// 加载模块
require(["module", "../app"], function(module, app) {...});

  • 优点:
    适合在浏览器环境中异步加载模块
    可以并行加载多个模块
  • 缺点:
    提高了开发成本,代码的阅读和书写比较困难,模块定义方式的语义不顺畅
    不符合通用的模块化思维方式,是一种妥协的实现

实现AMD规范代表require.js
3、CMD规范(异步加载模块)

define(function(require, exports, module) {
  var a = require('./a');
  a.doSomething();
  // 依赖就近书写,什么时候用到什么时候引入
  var b = require('./b');
  b.doSomething();
});
  • 优点:
    依赖就近,延迟执行
    可以很容易在 Node.js 中运行
  • 缺点:
    依赖 SPM 打包,模块的加载逻辑偏重

实现代表库sea.js:SeaJS对模块的态度是懒执行, SeaJS只会在真正需要使用(依赖)模块时才执行该模块

AMD 与 CMD 的区别:

  • 对于依赖的模块,AMD 是提前执行,CMD 是延迟执行。不过 RequireJS 从2.0开始,也改成了可以延迟执行(根据写法不同,处理方式不同)。CMD 推崇 as lazy as possible.
  • AMD推崇依赖前置;CMD推崇依赖就近,只有在用到某个模块的时候再去require。
    UMD
  • UMD是AMD和CommonJS的糅合
  • AMD 以浏览器第一原则发展异步加载模块。
  • CommonJS 模块以服务器第一原则发展,选择同步加载,它的模块无需包装。
  • UMD先判断是否支持Node.js的模块(exports)是否存在,存在则使用Node.js模块模式;在判断是否支持AMD(define是否存在),存在则使用AMD方式加载模块。

ES6模块化

  • ES6 在语言标准的层面上,实现了模块功能,而且实现得相当简单,完全可以取代 CommonJS 和 AMD 规范,成为浏览器和服务器通用的模块解决方案。
  • ES6 模块设计思想:尽量的静态化、使得编译时就能确定模块的依赖关系,以及输入和输出的变量(CommonJS和AMD模块,都只能在运行时确定这些东西)。

使用方式:

// 导入
import "/app";
import React from “react”;
import { Component } from “react”;
// 导出
export function multiply() {...};
export var year = 2018;
export default ...
...
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值