一個缺失已久的特性 — module模塊

1.jpg

在ES6之前,Javascript還不支持原生的模塊化。如果要實現模塊化,我們要借助一些框架,比如:requireJS或者seaJS等;什么?沒用過也沒聽過這些框架?沒關系,它們不是我們今天要講的重點。

今天的主角是:ES6自帶的模塊化。

模塊化的初衷

也許你要問了,好端端的,為什么要模塊化?

現在的web系統越來越龐大、復雜,需要團隊分工,多人協作,大型系統的javascript文件經常存在復雜的依賴關系,后期的維護成本會越來越高。

JavaScript模塊化正式為了解決這一需求而誕生。

竟然模塊化這么重要,我們看看ES6的module模塊是什么實現的?

Ps:目前還沒有瀏覽器支持ES6的module模塊。

假設現在有兩個js文件,分別是module-A.js和module-B.js,我們把它們視為兩個模塊。

帶著這個假設,下面我們來學習module模塊的幾個概念以及它們的含義。

模塊Module

模塊Module:一個模塊,就是一個對其他模塊暴露自己的屬性或者方法的文件。

在這里,我們會把module-A.js和module-B.js分別當作兩個模塊(moduleA模塊和moduleB模塊)來對待和處理。用這兩個模塊來演示如何暴露一個模塊的屬性或方法。

導出Export

導出Export:作為一個模塊,它可以選擇性地給其他模塊暴露(提供)自己的屬性和方法,供其他模塊使用。

導入Import

導入Import:作為一個模塊,可以根據需要,引入其他模塊的提供的屬性或者方法,供自己模塊使用。

模塊化的實現

帶著這三個概念,我們來演示一下它們的基本用法:

moduleB模塊代碼:


    //---module-B.js文件---

    //導出變量:name
    export var name = "前端君"; 

模塊B我們使用關鍵字export關鍵字,對外暴露了一個屬性:name的值為:字符串“前端君”。一個關鍵字,一句代碼就實現了,是不是很簡單。

模塊B演示了導出,接下來我們用模塊A來演示如何導入。

moduleA模塊代碼:


    //---module-A.js文件---

    //導入 模塊B的屬性 name
    import { name } from "./module-B.js";
    console.log(name)
    //打印結果:前端君

模塊A我們使用關鍵字import導入了模塊B的name屬性,并且賦值給變量name。關鍵字from的作用是指定你想要引入的模塊,我們這里指定的是module-B.js文件,也就是上面的模塊B。打印結果:“前端君”正是模塊B的對外暴露的屬性。

批量導出

對于模塊B,如果你想導出(暴露)多個屬性和方法的話,你可以這樣實現:


    //屬性name
    var name = "前端君";
    //屬性age
    var age  = 25;
    //方法 say
    var say = function(){
        console.log("say hello");
    }

    //批量導出
    export {name,age,say}

上面,我們定義了2個屬性和1個方法,最后用一個對象實現將它們批量導出。我們更推薦的是使用這種方法實現導出,因為當對外暴露的屬性和方法較多的時候,這種方法可以更直觀地看出當前模塊暴露了哪些變量。

而對于這種批量導出,我們導入的時候怎么對應上呢?


    //---module-A.js文件---

    //導入 模塊B的屬性 name
    import { name,age,say } from "./module-B.js";

    console.log(name)
    //打印結果:前端君

    console.log(age)
    //打印結果:25

    say()
    //打印結果:say hello

同樣,我們使用多個同名變量就可以獲取對應的屬性和方法,變量名字必須跟導出的一致才能準確獲取,位置順序無要求。

重命名導入的變量

也許你突發奇想,想給導入的變量換一個名字的話,你可以這樣做:


    import { name as myname } from "./module-B.js";

    console.log(myname)
    //打印結果:前端君

使用關鍵字as,可以實現給變量name更換名字為myname。最后正確輸出myname的值:“前端君”。

整體導入

我們還可以使用星號*實現整體導入:


    //使用*實現整體導入
    import * as obj from "./module-B.js";

    console.log(obj.name)
    //結果:"前端君"

    console.log(obj.age)
    //結果:25

    obj.say();
    //結果:say hello

使用星號符將模塊B提供的所有屬性和方法整體導入*賦值給變量obj,我們可以點運算符來獲取它的屬性和方法。

默認導出

默認導出,每個模塊支持我們導出一個沒有名字的變量,我們使用關鍵語句export default來實現


    export default function(){
        console.log("I am default Fn");
    }

我們使用export default關鍵字對外導出一個匿名函數,導入這個模塊的時候,可以為這個匿名函數取任意的名字,我們試一下導入上面那個匿名函數:


    //取任意名字均可
    import sayDefault from "./module-B.js";

    sayDefault();
    //結果:I am default Fn

同樣是使用import關鍵字導入模塊B,但是這次不需要使用大括號{ }。我們使用新的名字:sayDefault來代替導入的匿名函數,最后調用一下,打印結果正是模塊B默認導出的匿名函數的執行效果。

注意事項

1、聲明的變量,對外都是只讀的。


    //---module-B.js文件------
    var name = "前端君"
    export {name}

    //---module-A.js文件------
    import {name} from "./module-B.js";
    name = "修改字符串變量";
    //報錯:name is read-only

上面的代碼片段包含了2個模塊,其中,模塊B導出了字符串變量name,模塊A導出變量name之后試圖修改它的值,結果報錯。

但是,如果模塊B導出的是對象類型的值,就可修改


    //---module-B.js文件---
    var person = {"name":"前端君"}
    export { person }

    //---module-A.js文件------
    import {person} from "./module-B.js";
    person.name = "修改字符串變量";
    //修改成功

上面的代碼片段包含了2個模塊,模塊B導出了對象person,模塊A導入后,對其屬性name進行修改,結果修改成功,這一點大家要注意,并不是所有導出的變量都不可修改,對象類型就可修改。

2、導入不存在的變量,值為undefined。


    //---module-B.js文件---
    var name = "前端君";
    export {name}

    //---module-A.js文件------
    import { height } from "./module-B.js";
    console.log(height);
    //打印結果:undefined

模塊A想導入的變量height,在模塊B中并沒有提供,但這不會拋出異常,只是height的值為undefined。

module模塊的講解就到這里,ES6整個系列的連載也算完滿結束,但是ES6的學起還沒結束,周末會推出一期增值服務,如果你想進一步鞏固這么多天來的ES6學習,那么,敬請期待!

本節小結

總結:ES6自帶了module模塊,但目前瀏覽器并沒有支持。我們可以輕松實現導入導出,批量導出,默認導入export default,使用星號符*整體導入,as關鍵字實現重命名。

作者口述

OK,那么ES6的基本教程就到這里結束了,那么以后我還會出ES6的高階文章.那么從明天開始我開始寫Vue框架的文章.謝謝大家一直以來的支持.

在這里我給大家準備了很多的學習資料

其實你與阿里工程師的差距只差這些東西

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 前面的話 ??JS用"共享一切"的方法加載代碼,這是該語言中最易出錯且容易令人感到困惑的地方。在ES6以前,在應用...
    CodeMT閱讀 2,917評論 0 5
  • 官方中文版原文鏈接 感謝社區中各位的大力支持,譯者再次奉上一點點福利:阿里云產品券,享受所有官網優惠,并抽取幸運大...
    HetfieldJoe閱讀 3,668評論 2 27
  • 模塊通常是指編程語言所提供的代碼組織機制,利用此機制可將程序拆解為獨立且通用的代碼單元。所謂模塊化主要是解決代碼分...
    MapleLeafFall閱讀 1,192評論 0 0
  • 點擊此鏈接閱讀體驗更好Es6中的模塊默認導入導出及加載順序 前言 在前面一Es6中的模塊化Module,導入(im...
    itclanCoder閱讀 3,712評論 0 0
  • 今天,我邀請幾個朋友回老家祭棗神、參加曬棗活動。 老鄉們熱情招待我們,特以家鄉的風俗,唱山歌與我們歡笑。我們興趣大...
    桃園春曉閱讀 663評論 2 7