require和ES6 import的區別

js模塊化的進程裏,出現了不少模塊化的方案,commonjs,requirejs(AMD),CMD。隨着ES6標準的發佈,import/export的規範也被普遍使用了。只是瀏覽器的支持程度不高,須要配合轉碼工具使用。ES6的模塊化和以前社區的commonjs模塊化到底有什麼區別呢?瀏覽器

Commonjs的require和module.exports

  • require是個函數,動態加載,也所以
1.require導入是在運行時,理論上能夠在任意地方調用require導入模塊;
2.require()的路徑能夠是表達式:require('/app' + '/index');
3.require導出的是 module.exports對象
4.exports是對module.exports的一個引用,當module.exports指向變化,exports導出就會出問題了
  • require返回對應module.exports對象的淺拷貝
1.若是是module.exports裏的基本類型的值,會獲得該值的副本
2.若是是module.exports裏的對象類型的值,會獲得該值的引用

ES6的import和export

  • import在編譯時肯定導入
1.路徑只能是字符串常量
2.import會被提高到文件最頂部
3.導入的變量是隻讀的
  • import導入的是值引用,而不是值拷貝
1.模塊內部值發生變化,會對應影響到引用的地方
2.import導入與導出須要有一一映射關係,相似解構賦值。

代碼說明一下二者的區別app

Commonjs模塊化

// a.js
let a = 0;
const count = () => {
    a++;
}
setTimeout(function(){
    a++;
    console.log('in module the a is ' + a);
}, 500);
module.exports = {
    a,
    count,
};

// b.js
let foo = require('a.js');
foo.count();
setTimeout(function(){
    console.log('in require the a is ' + foo.a);
}, 1000);

// 輸出
// in the module the a is 2
// in the require the a is 0

由於foo是一份淺拷貝,因此a是require導入時export裏a的值;而count是一個函數,foo.count是這個函數的一個引用,因此調用時做用域是它聲明處同樣,也就是它修改的a是exports裏的,而不是foo.a。函數

Es6 module工具

// a.js
let a = 0;
const count = () => {
    a++;
}
setTimeout(function(){
    a++;
    console.log('in module the a is ' + a);
}, 500);
export {
    a,
    count,
};

// b.js
import { a, count } from 'a.js';
count();
setTimeout(function(){
    console.log('in require the a is ' + a);
}, 1000);

// 輸出
// in the module the a is 2
// in the require the a is 2

能夠看出,很重要的一個區別就是一個基本值是否會同步變化,requirejs

相關文章
相關標籤/搜索