引入
模块的规范
有了模块,我们可以更方便的使用别人的代码,想要什么功能,就加载什么模块。
JavaScript的模块规范有两种:CommonJS 和 AMD。
- CommonJS
node.js的模块系统,就是参照CommonJS规范实现的。 在CommonJS中,有一个全局性方法 require(),用于加载模块
例如有个数学模块math.js,就可以像下面这样加载
var math =require('math');
- 浏览器环境
对于服务器端:所有模块都存放在本地硬盘,可以同步加载完成,等待时间就是硬盘的读取时间
对于浏览器:模块都在服务器端,等待时间取决于网速的快慢,可能要等很长时间,浏览器处于 假死 状态
因此,浏览器端的模块,不能采用“同步加载”(sync),只能采用“异步加载”(asyn)。 这就是AMD规范诞生的北京
- AMD(Asynchronous Module Definition)
“异步模块定义”
它采用异步方式加载模块,模块的加载不影响它后面语句的运行。
所有依赖这个模块的语句,都定义在一个回调函数中,等到加载完成后,这个回调函数才会执行。
require,import 的区别
- 形式不同
require/exports 的用法只有以下三种简单的写法:
const fs = require('fs')
exports.fs = fs
module.exports = fs
而 import/export 的写法就多种多样:
import fs from 'fs'
import {default as fs} from 'fs'
import * as fs from 'fs'
import {readFile} from 'fs'
import {readFile as read} from 'fs'
import fs, {readFile} from 'fs'
export default fs
export const fs
export function readFile
export {readFile, read}
export * from 'fs'
- 本质区别
1.CommonJS还是ES6 Module输出都可以看成是一个具备多个属性或者方法的对象
2.default 是ES6 Module所独有的关键字,export default fs 输出默认的接口对象,import fs from ‘fs’ 可直接导入这个对象
3.ES6 Module中导入模块的属性或者方法是强绑定,包括基础类型;而CommonJS则是普通的值传递或者引用传递
3看个例子
// counter.js
exports.count = 0
setTimeout(function () {
console.log('increase count to', ++exports.count, 'in counter.js after 500ms')
}, 500)
// commonjs.js
const {count} = require('./counter')
setTimeout(function () {
console.log('read count after 1000ms in commonjs is', count)
}, 1000)
//es6.js
import {count} from './counter'
setTimeout(function () {
console.log('read count after 1000ms in es6 is', count)
}, 1000)
分别运行
➜ test node commonjs.js
increase count to 1 in counter.js after 500ms
read count after 1000ms in commonjs is 0
➜ test babel-node es6.js
increase count to 1 in counter.js after 500ms
read count after 1000ms in es6 is 1
自我理解:require相当于浅拷贝,相当于重新创建了对象
而import相当于赋值,赋值得到的只是将指针改变。不能在去赋值
(8.2 自我充电)