javascript基礎之模塊

什麼是ES6模塊?

在ES6中,每一個文件就是一個模塊,有本身的做用域。在一個文件裏面定義的變量、函數、類,都是私有的,對其餘文件不可見。在看到這裏的時候感受很熟悉,這不就是匿名函數自執行,而後一個個匿名函數放在一個個文件中的麼,一個模塊就是一個放在文件中的匿名自執行函數。二者對比就像下面這樣:javascript

// add.js 
(function(window){
    function add(a, b) {
       return a + b;
    }
    
    window.add = add // 經過window對象把 add 函數向外開放
})(window)

而使用ES6的模塊, 就像下面java

// add.js
function add(a, b) {
  return a + b;
}
export default add; // 經過export 導出 add方法

固然了,ES6的模塊確定是比匿名函數自執行更加高級的一種封裝了。相比於匿名函數,ES6模塊具備下面幾種特色。webpack

1. ES6默認使用嚴格模式, 而不須要使用 "use strict"
2. ES6模塊是編譯時加載,對代碼進行靜態分析
3. 對外拋出接口的時候,不會污染全局的對象
4. 可以有效的處理依賴, 並且只會在第一次加載模塊時,代碼運行一次。後面再次加載,不會重複 運行,會從緩存中讀取

......暫時這些,之後待補充

至於爲何時候ES6的模塊產生的歷史就不討論,網絡上不少。我的感受明白了它的歷史就能更好的明白它的特性。web

export 與 import

說到模塊,就須要想到兩點,一個是模塊的對外接口,後面文章中使用導出來表示,另一個是引入其餘模塊的接口,後面文章中使用導入來表示。緩存

export命令用於規定模塊的 導出import命令用於模塊的 導入

重頭戲就來了,怎麼更好更快的理解模塊的導出導入

當模塊引入其餘模塊的時候,最終是獲取其模塊導出的值(基本數據類型或者引用類型)。因而能夠這樣去理解,當咱們引入的模塊(文件)已經肯定下來了,那麼導入的值也就肯定下來。網絡

// add.js
function add(a, b) {
   return a + b;
}
export default add

// main.js
import add from './add.js'
add(1,2) // 3

上面導入的是 add.js 這個模塊,其實主要是把add.js 中的 add 函數進行引入。函數

當須要到導入多個值的時候,能夠經過對象來返回多個所須要的值。學習

// util.js
function add(a, b) {
   return a + b;
}

function reduce(a, b) {
   return a - b;
}
// 經過對象來返回多個值
export default {add: add, reduce: reduce};

// main.js
import util from './util.js'
console.log(util) // {add: add, reduce: reduce}

到這裏,我我的以爲模塊的導入導出基本上就已經很好了。由於這樣不論是導出仍是導入,對接的接口都是簡單方便。 code

固然這只是我以爲。仍是上面的例子對象

// util.js
function add(a, b) {
   return a + b;
}

function reduce(a, b) {
   return a - b;
}

export default {add: add, reduce: reduce, name: 'util'}

// main.js
import util from './util.js'

util.add(1, 2) // => 3

util.reduce(4, 3) // => 1

util.name // => 'util'

有人說,當導入的是值是對象的時候,須要屢次去使用對象獲取屬性。 就像上面須要屢次使用util去獲取屬性。ES6中不是有解構賦值麼,用來處理對象屢次獲取屬性的問題,那麼導入對象的時候,也能夠這樣去處理。

因而按照對象的解構賦值,對上面的 main.js 改變。

// main.js
import {add: addFn} from './util.js'
// 這裏在`webpack`中編譯就已經報錯了, ES6模塊不支持這種方式

// 使用另一種解構方式,`導出`模塊的屬性名與`導入`的變量名一致

// main.js
import { add } from './util.js'
console.log(add)  // undefined
// 這裏在`webpack`編譯中沒有報出錯誤,可是還有警告: "export 'add' was not found  

// 因而對 util.js 的`導出`進行改變
//util.js
 function add(a, b) {
   return a + b;
}

function reduce(a, b) {
   return a - b;
}

export {add, reduce, name: 'util'}
// 當修改完util.js 就完成了util.js模塊`導出` 與 main.js模塊的`導入`對接

模塊的導入導出大體能夠分爲兩種模式

1. default 模式

default 模式下,模塊中導出的值可使用任何類型(不論是基本類型仍是引用類型),均可以對外輸出。而導入的此模塊也是很簡單,提供一個接收的變量就能夠(推薦這種模式)
例子以下:

// util.js 
function add(a, b) {
  return a + b;
}
function reduce(a, b) {
  return a - b;
}

const obj = { add, reduce };

export default obj;
// main.js
import util from './util.js';
// util 是能夠變換任意名稱
console.log(util)// => {add: ƒ, reduce: ƒ}

2. { xxx } 模式

{ xxx } 是不須要在模塊導出的時候使用default的。可是這種方式下,導出的值必定是object的。
導入的模塊時是須要使用 { xxx }來接收。並且接收的變量名稱還必須與導出模塊屬性名的同樣。
例子以下:

// util.js 
function add(a, b) {
  return a + b;
}
function reduce(a, b) {
  return a - b;
}

let obj = { add, reduce };
// export obj; //webpack 編譯報錯

export { add, reduce };

// 除了這樣直接導出對象,還能夠像下面這樣

export let name = 'util';
// 與 export { name } 效果同樣;

深刻了解的話,二者仍是能夠一塊兒合用

function add(a, b) {
  return a + b;
}
function reduce(a, b) {
  return a - b;
}

export let name = 'util';
export { add, reduce };
// 至關於把這些屬性合併在一塊兒
// main.js
import { add, reduce, name } from './util.js' 
console.log(add) // add(a, b) { return a + b; }
console.log(name) // util
as 重命名

as 重命名主要是用於 { xxx }模式。由於在導出的時候,屬性名是被肯定下來,而在導入此模塊的時候,變量名須要跟此屬性名同樣才能獲取對應的值。而使用 as 不只可以幫助導出模塊把屬性名重命名,也可以幫導入模塊把接收的變量名進行重命名。
例子以下:

// util.js
function add(a, b) {
    return a + b;
}

export { add as addFn};
// main.js
import { addFn as add } from './util.js'

console.log(add) // add(a, b) { return a + b; }

上面是我的關於ES6的模塊我的理解和學習心得。

另外想要深刻了解的能夠查看官方文檔 http://www.ecma-international...

相關文章
相關標籤/搜索