模块化

模块化概念: 实现特定功能的一组方法

原始“类模块”写法

function m1(){}
function m2(){}

缺点:污染了全局变量,模块成员之间没直接关系

对象“类模块”写法

var module = new Object({
    _count:0,
    m1:function(){},
    m2:function(){}
})

缺点: 使用时直接调用对象属性,module.m1(),会暴露所有模块成员,内部状态可以被外部改写

立即执行函数写法(IIFE)

var module = (function(){
    var _count = 0;
    var m1 = function(){};
    var m2 = function(){}
    return{
      m1: m1,
      m2:m2
    }
})();

优点:不暴露私有成员,也不造成全局变量污染

此module就是JavaScript模块的基本写法

主流模块规范

ES6 module.
ES6之前:

  • CommonJS
  • AMD

CommonJS

  • 暴露模块使用module.exportsexports
  • 全局方法require()
  • CommonJS范围不适用于浏览器环境

AMD 和CMD采用require方式应用
浏览器的模块加载,同步容易阻塞,只能异步加载(AMD)
CMDAMD都是用 define()来定义模块,用require()来引用

AMD:Asynchronous Module Definition

  • 采用define()函数定义模块
    • define(id,dependencies,factory)
      • id字符串
      • dependencies 载入的依赖模块,使用相对路径,数组的形式
      • factory工厂方法 返回一个模块函数
  • AMD采用require([module],callback)语句加载模块
  • 满足AMD规范的库require.jscurl.js
define(thename, ['Lib'],function(Lib){})
//AMD的模块加载  不会发生假死。AMD适合浏览器环境
require(['math'],function(math){ })

CMD: Common Module Definition

  • 依赖就近,用的时候再require
  • 满足CMD规范的库:seajs
  • define(name,dependencies,function(require,exports,module){})
define('hello',['jquery'],function(require,exports,module){ //模块代码 })

AMD VS CMD

  • 均为异步加载模块
  • AMD依赖前置
  • CMD就近依赖

ES6 Module标准

  • 标准是以import引入模块,export导出模块
  • node技术遵循CommonJS规范,使用require引入模块,使用module.exportsexports导出接口

export

  • 导出函数、对象、指定文件(模块)的原始值
    • 命名式导出(名称导出)
    • 默认导出(定义式导出)
  • node中是exports

命名式导出

  • 导出多个值,import引用使用相同的名称。
  • export * from 'article' 使用*和from来实现模块的继承
  • 模块导出时,可以指定模块的导出成员
    • 导出的成员是类中的共有对象
    • 非导出成员是类中私有对象
  • export {name as siteName, domain:domain} 模块导出是as关键字对导出成员进行重命名。
  • export 1 导出接口时,必须与模块内部的变量具有意义对应关系。
  • export {a} 导出变量值a 即使a被赋值为function也是不允许写export a这种写法。
  • 模块中在末尾用一个export导出所有的接口。export {fun as default, a, b, c}
//一个模块里这样写
export function cube(){}
const foo = Math.PI;
export {foo};
//另一个模块引用
import {cube, foo} from ...

默认导出

  • 定义式导出
  • 默认导出只有单一值,可以是函数,类或其他类型的值。
  • import 导入比较容易。
  • export default Dexport {D as default}
//命名式导出多个模块
export const foo = Math.sqrt(2)  导出一个常量
export { name1, name2, name3}
export { variable as name1, variable as name, ...nameN }
export let name1,name2, ...nameN 

//导出定义的变量和常量
export let name1 = .., name2=...,nameN;

//默认导出,只能导出单个模块
export default expression;
export default function(){}
export default function name1(){}
export {name2 as default ,...}

//从已存在的模块,脚本文件..导出
export * from ..;
export {name1, name2} from ....;
export {import1 as name1, import2 as name2...,nameN} from ...

import

  • 从已导出的模块,脚本中导入函数,对象,指定文件的原始值。
  • 命名式导入与默认导入
//default
import default Member from "module-name";
//等同于export {a as default}
import * as name from "module-name";
import { member } from "module-name";
import { member as alias } from "module-name";
import { member1 , member2 } from "module-name";
import { member1 , member2 as alias2 , [...] } from "module-name";
import defaultMember, { member [ , [...] ] } from "module-name";
//*导入所有
import defaultMember, * as name from "module-name";
//导入一个模块不进行任何绑定
import "module-name";

Module.exports VS exports

  • Module.exports 全局变量
  • exports 局部变量
  • 每个js文件创建,都有var exports = module.exports ={} 这俩都指向同一个空对象
  • 这俩指向的内存地址相同。

你可能感兴趣的:(模块化)