对javascript模块化的一些总结…
原始写法
|
|
不同的函数简单放在一起,组成了一个模块,这样做污染了全局变量,模块成员之间看不出任何关系。
对象写法
|
|
这样的写法会暴露所有模块成员,内部状态可以被外部改写。
立即执行函数
|
|
这样可以达到不暴露私有成员的目的。
放大模式
如果一个模块很大,必须分成几个部分,或者一个模块需要继承另一个模块,这时就有必要采用”放大模式”
上面的代码为module1模块添加了一个新方法m3(),然后返回新的module1模块。
宽放大模式
在浏览器环境中,模块的各个部分通常都是从网上获取的,有时无法知道哪个部分会先加载。如果采用上一节的写法,第一个执行的部分有可能加载一个不存在空对象,这时就要采用”宽放大模式”。
与”放大模式”相比,"宽放大模式"就是”立即执行函数”的参数可以是空对象。
输入全局变量
独立性是模块的重要特点,模块内部最好不与程序的其他部分直接交互。
为了在模块内部调用全局变量,必须显式地将其他变量输入模块。
模块化需要解决的问题
- 如何安全的包装一个模块的代码?(不污染模块外的任何代码)
- 如何唯一标识一个模块?
- 如何优雅的把模块的API暴漏出去?(不能增加全局变量)
- 如何方便的使用所依赖的模块?
CommonJS
CommonJS模块可以很方便得将某个对象导出,让他们能够被其他模块通过 require 语句来引入。通过CommonJS,每个JS文件独立地存储它模块的内容(就像一个被括起来的闭包一样)。在这种作用域中,通过 module.exports 语句来导出对象为模块,再通过 require 语句来引入。1234567891011function myModule() {this.hello = function() {return 'hello!';}this.goodbye = function() {return 'goodbye!';}}module.exports = myModule;
|
|
有两个好处:
- 避免了全局命名空间污染
- 明确了代码之间的依赖关系
需要注意的一点是,CommonJS以服务器优先的方式来同步载入模块,假使我们引入三个模块的话,他们会一个个地被载入。
它在服务器端用起来很爽,可是在浏览器里就不会那么高效了。毕竟读取网络的文件要比本地耗费更多时间。只要它还在读取模块,浏览器载入的页面就会一直卡着不动。
AMD
假使我们想要实现异步加载模块该怎么办?答案就是Asynchronous Module Definition(异步模块定义规范),简称AMD.
这里使用 define 方法,第一个参数是依赖的模块,这些模块都会在后台无阻塞地加载,第二个参数则作为加载完毕的回调函数。
UMD
在一些同时需要AMD和CommonJS功能的项目中,你需要使用另一种规范:Universal Module Definition(通用模块定义规范)。
UMD创造了一种同时使用两种规范的方法,并且也支持全局变量定义。所以UMD的模块可以同时在客户端和服务端使用。
ES6模块
ES6 模块功能的特性是,导入是实时只读的。(CommonJS 只是相当于把导出的代码复制过来)。
|
|