1.目前其實我們所用到的import都是通過babel轉成require的,瀏覽器則是通過webpack等打包工具將這些**打包成乙個個檔案的
commonjs:
var b = require('./b');
console.log(b.a);
settimeout(() => , 1000);
let a = 1;
settimeout(() => a = 2, 500);
module.exports = ;
node a 結果:1 1 1
es6:
import from './b';
console.log(b);
settimeout(() => , 1000);
export let a = 1;
settimeout(() => a = 2, 500);
node --experimental-modules a.mjs 結果:1 2
可以發現兩者的區別在於,commonjs 模組輸出的是值的拷貝,眾所周知,commonjs引入模組需要路徑分析、檔案定位、編譯執行、對於擴充套件名為js的檔案先通過fs同步讀取檔案然後編譯執行,在編譯的過程中會將讀取檔案新增以下包裝
(function (exports, require, module, __filename, __dirname) ;
包裝後執行類似eval的方法runinthiscontext返回乙個具體的函式(不然就是一堆字串了),然後就是把當前模組的一些引數和模組物件自身等一些引數傳進去了,看上去是不是像閉包?其實就是乙個閉包,使得檔案之間的作用域隔離了,模組的exports屬性返回給呼叫方(值拷貝),別的一些變數在這個編譯函式執行完就被銷毀了。那既然這個是閉包,那是否可以利用閉包的特性訪問到模組內的區域性變數並且當其值,外部也能給獲取到改變的值呢,答案是可以的。
a.js:
var b = require('./b');
console.log(b.fn());
settimeout(() => , 1000);
b.js:
let a = 1;
settimeout(() => a = 2, 500);
module.exports = };
node a 結果:1 2
es6就比較厲害了,在使用模組時,通過入口和import語句,會先建立乙個模組依賴圖,然後將這些檔案解析為乙個個的模組記錄的資料結構,然後就是例項化,將所有匯出的值存放在合適的記憶體中,然後匯出和匯入都指向同乙個記憶體位址,最後就是執行編碼,將值放在對應的記憶體位址中。總的來說就是構造、例項化、求值。所以說由於es6是事先建立乙個模組依賴圖,然後求值,所以模組識別符號不能有變數(現在有乙個dynamic import提案可以解決這個問題),這就是所謂的靜態,然commonjs是執行時載入的,就是所謂的動態
es6模組的靜態編譯有兩個特點:
1.import優先於模組內的其他內容執行
2.export 命令會有變數宣告。
console.log(a);
import from './b';
console.log(a)
export var a = 1;
console.log("我是模組內部")
node --experimental-modules a.mjs
結果:undefined 我是模組內部 1
推薦一篇文章:es modules: a cartoon deep-dive
ES6學習筆記之ES6中的模組
1 import和export基本使用 重點 在es6中新增了js檔案的暴露和引入的新寫法 import和export node es6 require import exports.export module.exports default 使用export const 暴露函式名暴露函式,imp...
es6 模組化(es6學習筆記07)
模組化 是指將乙個大的程式檔案,拆分成許多小的檔案,然後將小檔案組合起來。功能模組主要由兩個命令構成 export和import 1.2.1 export 使用 1.分別暴露 export let book 西遊記 export function like 2.統一暴露 let book 西遊記 f...
JS筆記 ES6模組
es6最大的改進就是引入了模組規範。與關聯或者通過import語句載入的j ascript檔案會被認定為模組。模組匯入匯出 兩種匯入與兩種匯出一一對應 匯出 const foo string foo 預設匯出 export default foo 每個模組只有能乙個預設匯出 匯入 import 語句...