ES6—class與模塊化(9)

JavaScript語言自創立之初,一直沒有模塊(module)體系,沒法將一個大程序拆分紅互相依賴的小文件,再用簡單的方法拼裝起來。javascript

不少編程語言都有這項功能,好比 Python的import、Ruby的require,甚至就連CSS都有@import,可是JavaScript沒有這方面的支持,這增長了開發大型的、複雜的項目時的難度。前端

因而前端開發者們開始想辦法,爲了防止命名空間被污染,採用的是命名空間的方式。vue

在ES6以前,一些前端社區制定了模塊加載方案,最主要的有CommonJS和AMD兩種。前者用於服務器,後者用於瀏覽器。java

但這兩種規範都由開源社區制定,沒有統一,而ES6中引入了模塊(Module)體系,從語言層在實現了模塊機制,實現了模塊功能,並且實現得至關簡單,爲JavaScript開發大型的、複雜的項目掃清了障礙。react

ES6中的模塊功能主要由兩個命令構成:export和import。webpack

export命令用於規定模塊的對外接口,import命令用於輸入其餘模塊提供的功能,兩者屬於相輔相成、一一對應關係。web

1、什麼是模塊
圖片描述編程

模塊能夠理解爲函數代碼塊的功能,是封裝對象的屬性和方法的javascript代碼,它能夠是某單個文件、變量或者函數。瀏覽器

模塊實質上是對業務邏輯分離實現低耦合高內聚,也便於代碼管理而不是全部功能代碼堆疊在一塊兒,模塊真正的魔力所在是僅導出和導入你須要的綁定,而不是將全部的東西都放到一個文件。服務器

在理想狀態下咱們只須要完成本身部分的核心業務邏輯代碼,其餘方面的依賴能夠經過直接加載被人已經寫好模塊進行使用便可。

2、export 導出 命令

一個模塊就是一個獨立的文件,該文件內部的全部變量,外部沒法獲取。若是想從外部可以讀取模塊內部的某個變量,就必須使用export關鍵字輸出該變量。分爲如下幾種狀況:

(1)在須要導出的lib.js文件中, 使用 export{接口} 導出接口, 大括號中的接口名字爲上面定義的變量, import和引入的main.js文件中的export是對應的:

//lib.js 文件
let bar = "stringBar";
let foo = "stringFoo";
let fn0 = function() {
    console.log("fn0");
};
let fn1 = function() {
    console.log("fn1");
};
export{ bar , foo, fn0, fn1}

//main.js文件
import {bar,foo, fn0, fn1} from "./lib";
console.log(bar+"_"+foo);
fn0();
fn1();

(2)在export接口的時候, 咱們可使用 XX as YY, 把導出的接口名字改了, 好比: xiaoming as haoren,

這樣作的目的是爲了讓接口字段更加語義化。

//lib.js文件
let fn0 = function() {
    console.log("fn0");
};
let obj0 = {}
export { fn0 as foo, obj0 as bar};

//main.js文件
import {foo, bar} from "./lib";
foo();
console.log(bar);

圖片描述

(3)直接在export的地方定義導出的函數,或者變量:

//lib.js文件
export let foo = ()=> {console.log("fnFoo") ;return "foo"},bar = "stringBar";

//main.js文件
import {foo, bar} from "./lib";
console.log(foo());
console.log(bar);

(4)不須要知道變量名字(至關因而匿名的)的狀況,能夠 直接把開發的接口給export。若是一個js模塊文件就只有一個功能, 那麼就可使用export default導出。

//lib.js
export default "string";

//main.js
import defaultString from "./lib";
console.log(defaultString);

這樣作的好處是其餘模塊加載該模塊時,import命令能夠爲該匿名函數指定任意名字。

(5)export也能默認導出函數, 在import的時候, 名字能夠自定義, 由於每個模塊的默認接口就一個:

//lib.js
let fn = () => "string";
export {fn as default};

//main.js
import defaultFn from "./lib";
console.log(defaultFn());

(6)使用通配符* ,從新導出其餘模塊的接口

//lib.js
export * from "./other";
//若是隻想導出部分接口, 只要把接口名字列出來
//export {foo,fnFoo} from "./other";

//other.js
export let foo = "stringFoo", fnFoo = function() {console.log("fnFoo")};

//main.js
import {foo, fnFoo} from "./lib";
console.log(foo);
console.log(fnFoo());

3、import 導入命令

ES6導入的模塊都是屬於引用,每個導入的js模塊都是活的, 每一次訪問該模塊的變量或者函數都是最新的, 這個是原生ES6模塊 與AMD和CMD的區別之一。

使用export命令定義了模塊的對外接口之後,其餘 JS 文件就能夠經過import命令加載這個模塊。

//main.js文件
import {bar,foo, fn0, fn1} from "./lib";
console.log(bar+"_"+foo);
fn0();
fn1();

大括號裏面的變量名,必須與被導入模塊對外接口的名稱相同。

想要輸入的變量從新取一個名字,import命令要使用 as關鍵字,將輸入的變量重命名。

import { formatFn as fn0 } from 'lib.js';

注:import後面的from指定模塊文件的位置,能夠是相對路徑,也能夠是絕對路徑,.js後綴能夠省略。

圖片描述

4、ES6模塊化的基本規則、特色

一、每個模塊只加載一次, 每個JS只執行一次, 若是下次再去加載同目錄下同文件,直接從內存中讀取。 一個模塊就是一個單例,或者說就是一個對象。

二、每個模塊內聲明的變量都是局部變量, 不會污染全局做用域。

三、模塊內部的變量或者函數能夠經過export導出。

四、一個模塊能夠導入別的模塊。

5、class與模塊化相結合實例

結合上節課咱們學的 ES6 class與面向對象編程的知識,咱們再實現一個把class和模塊化結合的例子。

首先咱們建立一個parent.js文件,使用class類的寫法建立一個Parent類:

const name = "tom";
const age = "20";

class Parent{
  hw(){
    console.log(`hello world`)
  }
  static obj(){
      console.log('obj')/*表示爲靜態方法不回唄實例繼承,而是直接經過類調用。*/
    }
}  
var parent = new Parent()
parent.hw()//hell world

export{name,age,Parent}

以後在child.js中分別引入parent.js中的name、age、Parent

import {name,age,Parent} from './parent'


class Child extends Parent{
    constructor(obj){
        //就是new命令自動跳用方法。一個類必需要有constructor,若是沒定義,有默認添加一個空的。
        super()//調用父類的constructor()
        this._config = obj;
        console.log(obj.name+"年齡"+obj.age)
    }
    hw(){
      console.log("hw")
    }
    set val(value){
      this._config.name = value;
      console.log(`name=${value}`)
    }
    get val(){
      console.log(this._config.name);
    }
}

Child.obj()//obj 繼承父類static方法
var model = new Child({name,age}) //tom年齡20
model.hw()//hw
model.val = "jock"; //name=jock
model.val//jock

圖片描述

6、總結

本文主要從什麼是模塊,模塊的導出(導出變量、函數、類、文件等),模塊的導入(單個導入、多個導入、導入整個)等角度講述了ES6模塊化操做。

ES6模塊的設計思想,是儘可能的靜態化,使得編譯時就能肯定模塊的依賴關係,以及輸入和輸出的變量。CommonJS和AMD模塊,都只能在運行時肯定這些東西。好比 CommonJS模塊就是對象,輸入時必須查找對象屬性。

模塊打包如今最好用的就是webpack了,webpack做爲一款新興的模塊化管理和打包工具,其視任意文件都爲模塊,並打包成bundle文件,相比於browserify更增強大。

模塊化開發是前端開發的一大趨勢,好比你們去看vue、react、angular,或者大家公司的項目源碼,你會發現,幾乎全部項目都使用了模塊化。小夥伴們必定要緊跟時代的大潮,將組件化開發,模塊化開發,自動化構建結合,探索高效的開發之道。

相關文章
相關標籤/搜索