模块化概念: 实现特定功能的一组方法
原始“类模块”写法
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.exports
和exports
- 全局方法
require()
- CommonJS范围不适用于浏览器环境
AMD 和CMD采用
require
方式应用
浏览器的模块加载,同步容易阻塞,只能异步加载(AMD)
CMD与AMD都是用define()
来定义模块,用require()
来引用
AMD:Asynchronous Module Definition
-
采用
define()
函数定义模块-
define(id,dependencies,factory)
-
id
字符串 -
dependencies
载入的依赖模块,使用相对路径,数组的形式 -
factory
工厂方法 返回一个模块函数
-
-
- AMD采用
require([module],callback)
语句加载模块 -
满足AMD规范的库:
require.js
和curl.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.exports
或exports
导出接口
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 D
与export {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 ={}
这俩都指向同一个空对象 - 这俩指向的内存地址相同。
网友评论