1.前言
commonjs中使用module.exports,exports和require组合来实现文件的引入,ES6模块则使用export和import来实现,那他们究竟有什么区别,我们就来一起讨论一下。
2.具体区别
commonjs和ES6
- CommonJS模块输出的是一个值的拷贝,ES6 模块输出的是值的引用。commonjs是基于node环境中运行的,使用require来加载模块的时候是同步的,也就是说只有等第一个模块加载完成后,才会加载第二个,在服务器中加载本地文件是很快的,只需要到相应的位置去读区就行,而在浏览器中,则会收到网速等因素的影响,可能会使浏览器出现假死的情况,显然是不太合适的。
- CommonJS 模块是运行时加载,ES6 模块是编译时输出接口。 commonjs在第一次加载时运行了一次,由于它输出的是一个值的拷贝,我们暂时理解成一个对象,下面会做说明,第一次加载时会生成这个对象,并且缓存起来,之后require相同的模块则不会再进行加载,而是从缓存的对象中取出。
const data=require(./content.js)
//从content中取出一个经过拷贝的对象,命名为data。
ES6则输出一个路径,在import的时候在对应的路径下只取出我们需要的值,defaut的情况下面会做说明。
import {name,age,six} from './content.js'
//编译时只取出我们需要的
module.exports,exports和export
在CommonJs中,规定用module来表示当前的模版,exports来表示模版输出的接口,所以才有了module.exports的形式,我们只需要给exports属性赋值,不需要对值进行命名。require时引入所有module对象下的exports属性下的所有值。
//content.js
module.exports={
name:'zhangsan',
age:'18',
six:'nan'
}
//index.js
const data = require(./content.js)
console.log(data.name)
//一次性全部引入整个对象,部分消费
我们可以这么理解,默认modole.exports={},这个指向是不能改变的。
module.exports=const data=1 //错误写法,改变了modole.exports的指向
module.exports.data=1 //正确写法,
exports可以看做成modole.exports的指向。
let module={
exports:{}
}
let exports=module.exports //此时exports和modole.exports指向同一路径
console.log(exports===module.exports) //true
// exports在不改变指向的情况下是可以改变module.exports中的值,为了产生不必要的麻烦,最好都使用module.exports
在ES6中,由于要做到动态引入,所以输出的对象应该是一个个单独的对象,而不是整个所有对象的集合。因此,export 需要和模块内的变量建立对应关系。
//content.js
export const name='zhangsan'
export const age='18'
export const six='nan'
//index.js
import {name,age} from './content.js'
//动态引入需要的值,
export default 'zhangsan' === export const defalut='zhangsan'
import name from './content.js'
//可以把export default看做成输出一个变量名为default的值,在import引入时,可以自定义default的名字。
import和require
1.import有多种写法。require只有一种
import fs from 'fs'
import {readFile} from 'fs' //从 fs 导入 readFile 模块
import {default as fs} from 'fs' //从 fs 中导入使用 export default 导出的模块
import * as fileSystem from 'fs' //从 fs 导入所有模块,引用对象名为 fileSystem
import {readFile as read} from 'fs' //从 fs 导入 readFile 模块,引用对象名为 read
const data=require(./content.js)
2.import引入的是一个模块的地址,默认是只读的,但是在不改变指向的情况下,可以改变模块里变量的值,所有用到这个值的地方数据都会改变。而require引入的是一个经过拷贝的对象,改变它的值,原模版里的值无法改变。
//index.js
import fs from './content.js'
console.log(fs.name) // 'zhangsan'
fs.name='lisi'
//index2.js
import fs from './content.js'
console.log(fs.name) //'lisi'
//index2.js
import fs from './content.js'
fs.name=funtion add(){} //报错,改变了fs.name的指向了。
3.import命令具有提升效果,可以先使用后加载,require必须先加载才能使用。
console.log(name)
import { name } from './content.js';
以上分享纯属个人理解,如果有问题请大家指出来,本人也在不断的学习和理解中,随时更新文章。