ES6模块化与CommonJs模块化

一、语法运行方式

CommonJs模块的require是同步加载模块,

  • require命令加载某个模块时,会运行整个代码。
  • require加载同一个模块时,将会读取缓存

ES6模块的import是异步加载模块

二、加载方式

CommonJS模块是运行时加载
以下代码的实质是整体加载fs模块(即加载fs的所有方法),生成一个对象(_fs),然后再从这个对象上面读取 3 个方法。这种加载称为“运行时加载”,因为只有运行时才能得到这个对象,导致完全没办法在编译时做“静态优化”

// CommonJS模块
let { stat, exists, readfile } = require('fs');

// 等同于
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;

ES6模块是编译时输出接口
以下代码的实质是从fs模块加载 3 个方法,其他方法不加载。这种加载称为“编译时加载”或者静态加载,即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高。当然,这也导致了没法引用 ES6 模块本身,因为它不是对象。ES6的import会提升至开头

import { stat, exists, readFile } from 'fs';

三、输出值的区别

CommonJS模块化:对输出值的复制

//exCommon.js
let count = 1;
function incCount() {
    count++;
}
module.exports = {
    count,
    incCount
}

//useCommon.js
const C_mdu = require('./exCommon');
console.log(C_mdu.count);//1
C_mdu.incCount();
console.log(C_mdu.count);//1
  • 对于基本数据类型,为直接复制,即模块中值再发生改变不影响已引入模块值
  • 对于引用类型,为浅拷贝,因与模块中值为一个指针,即值互相影响

ES6模块化:对值的引用 【动态只读引用】

//exES.js
let count = 1;
function incCount() {
    count++;
}
module.exports = {
    count,
    incCount
}

//useES.js
import * as ES_mdu from './exES.js';
console.log(ES_mdu.count);//1
ES_mdu.incCount();
console.log(ES_mdu.count);//2
  • 对于只读,import命令将会生成一个只读引用,不可在模块外修改
  • 对于动态,原始值发生改变时,import加载的值一样会发生改变

四、循环加载

案例文章 - CSDN - commonjs和ES6及requirejs模块循环引用
CommonJs : 循环加载时,属于加载时执行。即脚本代码在require的时候,就会全部执行。一旦出现某个模块被"循环加载",就只输出已经执行的部分,还未执行的部分不会输出。

ES6:循环加载时,ES6模块是动态引用。只要两个模块之间存在某个引用,代码就能够执行。

五、使用方法

CommonJs

module.exports 和exports俩者无区别,exports为node简化语法,最终暴露的结果,都是以 module.exports 所指向的对象为准
exports.xxx,相当于在导出对象上挂属性,该属性对调用模块直接可见
exports =相当于给exports对象重新赋值,调用模块不能访问exports对象及其属性

//exCommon.js
//commonJs模块化 导出
let count = 1;
function incCount() {
    count++;
    console.log("CommonJs当前计数为:",count);
}
module.exports = {
    count,
    incCount
}
//useCommon.js
//commonJs模块化 导入
const C_mdu = require('./exCommon');
console.dir(C_mdu);//{ count: 1, incCount: [Function: incCount] }

ES6

//exES.js
//ES6模块化 导出方法一
export let count = 1;
export function incCount() {
    count++;
    console.log("ES6,当前计数为:" + count);
}
//useES.js
//ES6模块化 导入方法一
import { count, incCount } from "./exES.js";
//ES6模块化 导入方法二 as起别名
import * as ES_mdu from "./exES.js";
console.dir(ES_mdu);//{ count: 1, incCount: [Function: incCount] }

es6使用export default

// 如果一个js模块文件就只有一个功能, 那么就可以使用export default导出
// 一个模块不能具有多个默认导出
// 暴露.js 
export default {
  name: 'xiaoming'age: 18
}; 
// 引用.js
import person from '暴露.js'

参考文章 - CommonJS和ES6模块化的区别
参考文章 - commonjs与es6模块化有什么区别

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值