1. 區(qū)別:
1、CommonJS輸出的是一個值的拷貝,ES6輸出的是值的引用;
2、CommonJS是運行時加載,ES6是編譯時輸出接口;
3、CommonJS的require是同步加載模塊,ES6的import是異步加載,有獨立模塊依賴的解析階段。
1.1CommonJS 模塊輸出的是一個值的拷貝,ES6 模塊輸出的是值的引用
commonjs的用法,我們一起來看一下
1.首先創(chuàng)建一個lib.js的文件
// lib.js
const counter = 3;
const incCounter = ()=>{
counter++
}
module.exports = {
counter,
incCounter
}
2.再次創(chuàng)建一個main.js,使用commonjs的方式導(dǎo)入
// main.js
var lib = require('./lib');
console.log(lib)
console.log(lib.counter); // 3
lib.incCounter();
console.log(lib.counter); // 3
lib.js模塊加載以后,它的內(nèi)部變化就影響不到輸出的lib.counter了。這是因為mod.counter是一個原始類型的值,會被緩存;
esmodule的用法,我們一起來看一下
// lib.js
export let counter = 3;
export function incCounter () {
counter++;
}
// main.js
import { counter, incCounter } from './util.mjs'
console.log(counter); //3
incCounter()
console.log(counter) //4
ES6 模塊不會緩存運行結(jié)果,而是動態(tài)地去被加載的模塊取值,并且變量總是綁定其所在的模塊。
補充:通過esmodule導(dǎo)入的變量是不能重新賦值修改的。
1.2、CommonJS 模塊是運行時加載,ES6 模塊是編譯時輸出接口
// CommonJS模塊
let { stat, exists, readFile } = require('fs');
// 等同于
let _fs = require('fs');
let stat = _fs.stat;
let exists = _fs.exists;
let readfile = _fs.readfile;
上面代碼的實質(zhì)是整體加載fs模塊(即加載fs的所有方法),生成一個對象(_fs),然后再從這個對象上面讀取 3 個方法。這種加載稱為“運行時加載”,因為只有運行時才能得到這個對象,導(dǎo)致完全沒辦法在編譯時做“靜態(tài)優(yōu)化”。因此commonjs屬于再運行時才會加載模塊的方式。
import { stat, exists, readFile } from 'fs';
上面代碼的實質(zhì)是從fs模塊加載 3 個方法,其他方法不加載。這種加載稱為“編譯時加載”或者靜態(tài)加載,即 ES6 可以在編譯時就完成模塊加載,效率要比 CommonJS 模塊的加載方式高;
1.3、CommonJS 模塊的require()是同步加載模塊,ES6 模塊的import命令是異步加載,有一個獨立的模塊依賴的解析階段
同步加載:所謂同步加載就是加載資源或者模塊的過程會阻塞后續(xù)代碼的執(zhí)行;
異步加載:不會阻塞后續(xù)代碼的執(zhí)行;
我們來看一個案例,創(chuàng)建如下的目錄;
| -- a.js
| -- index.js
| -- c.js
// a.js
console.log('a.js文件的執(zhí)行');
const importFun = () => {
console.log(require('./c').c);
}
importFun()
module.exports = {
importFun
}
// index.js
const A = require('./a');
console.log('index.js的執(zhí)行');
// c.js
console.log('c.js的運行');
const c = 3
module.exports = {
c
}
執(zhí)行命令 node index.js
// a.js文件的執(zhí)行
// c.js的運行
// 3
// index.js的執(zhí)行
我們會發(fā)現(xiàn),require的內(nèi)容會阻塞后續(xù)代碼的執(zhí)行。因為c.js先打印出來,然后在是index.js的打印,所以說require()是同步加載的;
// a.js
console.log('a.js文件的執(zhí)行');
export const importFun = () => {
import('./c.js').then(({c})=>{
console.log(c)
})
}
importFun()
// index.js
import {importFun} from './a.js'
console.log('index.js的執(zhí)行');
// c.js
console.log('c.js的運行');
export const c = 3
// 結(jié)果
// a.js文件的執(zhí)行
// index.js的執(zhí)行
// c.js的運行
// 3
可以看的出來:import()是異步加載資源的,因為c.js是在index.js的后面打印出來的,并不會阻塞后續(xù)代碼的執(zhí)行;
2.總結(jié):
以上便是commonjs和esmodule的幾個區(qū)別
1: CommonJS 模塊輸出的是一個值的拷貝,ES6 模塊輸出的是值的引用
2: CommonJS 模塊是運行時加載,ES6 模塊是編譯時輸出接口文章來源:http://www.zghlxwxcb.cn/news/detail-446886.html
3: CommonJS 模塊的require()是同步加載模塊,ES6 模塊的import命令是異步加載,有一個獨立的模塊依賴的解析階段文章來源地址http://www.zghlxwxcb.cn/news/detail-446886.html
到了這里,關(guān)于es6與commonjs 的區(qū)別的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!