寫在前面,目前瀏覽器對ES6的import支持還不是很好,須要用bable轉譯。vue
ES6引入外部模塊分兩種狀況:瀏覽器
1.導入外部的變量或函數等;函數
import {firstName, lastName, year} from './profile';
2.導入外部的模塊,並當即執行spa
import './test' //執行test.js,但不導入任何變量
第2種狀況就不用講了,就是執行從頭至尾執行引入的js文件,固然,會忽略js文件裏export。3d
下面詳細講第1種狀況。code
兩個js文件,counter.js與my.jsblog
// counter.js import {a} from './my'; console.log('333333'); console.log(a);
// my.js console.log('111111'); export var a = 'aaaaaaa'; console.log('222222');
運行的結果是什麼呢?io
貌似沒什麼問題,再看看轉譯後的counter.jsconsole
//#----------------mod start---------------- void function (module, exports){ window["60ae5ba7"] = {}; "use strict"; // my.js console.log('111111'); window["60ae5ba7"].a = 'aaaaaaa'; console.log('222222'); }({exports:{}}, {}) //#----------------mod end---------------- //#----------------mod start---------------- void function (module, exports){ window["3d4fdd69"] = {}; "use strict"; // counter.js var my_1 = window["60ae5ba7"]; console.log('333333'); console.log(my_1.a);
好,暫時不用管那麼多。下面來問題了,我們把console.log(a)這句去掉,看看運行結果編譯
// counter.js import {a} from './my'; console.log('333333'); // console.log(a);
咦,只輸出這一句了?咱們明明引入了my模塊了,爲什麼模塊裏的代碼沒有執行呢。
這要從ES6模塊加載的實質談起。在阮一峯的ES6入門一書裏講到:ES6模塊的運行機制與CommonJS不同,它遇到模塊加載命令import
時,不會去執行模塊,而是隻生成一個動態的只讀引用。等到真的須要用到時,再到模塊裏面去取值,換句話說,ES6的輸入有點像Unix系統的「符號鏈接」,原始值變了,import
輸入的值也會跟着變。
但是按照上面說的,那有console.log(a)的時候,應該是輸出3333,1111,2222的順序,而不是1111,2222,333的順序呀。我猜想是上面講的不細緻的緣由,應該分爲編譯時和運行時來講。ES6的這種加載稱爲「編譯時加載」或者靜態加載,即 ES6 能夠在編譯時就完成模塊加載,在編譯的時候,發現了後面有使用到a的地方,就在運行時遇到import的地方直接執行了模塊的代碼。固然只是本身的猜想。
有一點別忘了:模塊內部的變量不向外暴露的話,外界是沒法使用這些內部變量的。全部有時候會看到,這個模塊引用了一個vue.js,另一個模塊也要引用vue.js,這是由於vue.js內部不少東西沒有暴露,因此都須要引用。