[TOC]
历史上,JavaScript 一直没有模块(module)体系,无法将一个大程序拆分成互相依赖的小文件,再用简单的方法拼装起来。其他语言都有这项功能,比如 Ruby 的require、Python 的import,甚至就连 CSS 都有@import,但是 JavaScript 任何这方面的支持都没有,这对开发大型的、复杂的项目形成了巨大障碍。
下面比较现有的三种模块化编程方案:
- CommonJS
- AMD
- ES6
比较:
- CommonJS大多数用于服务器端开发,运行时加载
- AMD大多数用于浏览器客户端开发,运行时加载
- ES6:编译时加载,尽量实现静态化
CommonJS
- 一般用于服务器端
- NodeJS是CommonJS规范的实现12var math = require('math');math.add(2,3); // 5
require是同步的
AMD(异步模块定义)
- 一般用于浏览器客户端
- 包含:RequireJs
require是同步的对服务器端不是一个问题,因为所有的模块都存放在本地硬盘,可以同步加载完成,等待时间就是硬盘的读取时间。但是,对于浏览器,这却是一个大问题,因为模块都放在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于”假死”状态。
因此,浏览器端的模块,不能采用”同步加载”(synchronous),只能采用”异步加载”(asynchronous)。这就是AMD规范诞生的背景。
AMD也适用require,但是使用回调函数执行后面动作12345require(['math'], function (math) {math.add(2, 3);});
ES6
ES6 模块的设计思想是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。CommonJS 和 AMD 模块,都只能在运行时确定这些东西。比如,CommonJS 模块就是对象,输入时必须查找对象属性
- ES6可以通过模块接口取到模块内部实时的值,这一点与 CommonJS 规范完全不同,CommonJS 模块输出的是值的缓存,不存在动态更新
- ES6的模块化是在编译时加载的,有作用域提升的效果
- ES6中import是静态执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构
【潦草记录】