ES6 模塊加載export 、import、export default 、import() 語法與區別,筆記總結

ES6模塊加載export 、import、export default 、import() 語法與區別
在 ES6 之前,社區制定了一些模塊加載方案,最主要的有 CommonJS 和 AMD 兩種。
CommonJS 用於服務器,AMD 用於瀏覽器。
ES6 在語言標準層面上,實現了模塊功能,而且簡單,完全可以取代 CommonJS 和 AMD 規範,成爲瀏覽器和服務器通用的模塊解決方案。

ES6 的模塊自動採用嚴格模式,不管你有沒有在模塊頭部加上"use strict";。
嚴格模式主要有以下限制。
變量必須聲明後再使用
函數的參數不能有同名屬性,否則報錯
不能使用with語句
不能對只讀屬性賦值,否則報錯
不能使用前綴 0 表示八進制數,否則報錯
不能刪除不可刪除的屬性,否則報錯
不能刪除變量delete prop,會報錯,只能刪除屬性delete global[prop]
eval不會在它的外層作用域引入變量
eval和arguments不能被重新賦值
arguments不會自動反映函數參數的變化
不能使用arguments.callee
不能使用arguments.caller
禁止this指向全局對象
不能使用fn.caller和fn.arguments獲取函數調用的堆棧
增加了保留字(比如protected、static和interface)
上面這些限制,模塊都必須遵守。由於嚴格模式是 ES5 引入的,不屬於 ES6,所以請參閱相關 ES5 書籍。

其中,尤其需要注意this的限制。ES6 模塊之中,頂層的this指向undefined,即不應該在頂層代碼使用this。

//index.js
//export 命令
            var a = 'a';
            var b = 'b';
            var c = 'c';
            //命令規定的是對外的接口,必須與模塊內部的變量建立一一對應關係。用大括號
            export {
                a,b,c
            }
            export var d = 'd';
            export {d}
            export function f(){}
            export {f}
            //報錯
            export 1;
            // 報錯
            var m = 1;
            export m;
            // 報錯
            function f() {}
            export f;
--------------------------------------------------------------------------------------------
            //export重命名語句 原命名 as 新命名
            export {
                a as m,
                b as n
            }
--------------------------------------------------------------------------------------------
            //export語句輸出的接口,與其對應的值是動態綁定關係,即通過該接口,可以取到模塊內部實時的值。
            //輸出變量foo,值爲bar,500 毫秒之後變成baz。
            //這一點與 CommonJS 規範完全不同。CommonJS 模塊輸出的是值的緩存,不存在動態更新
            export var foo = 'bar';
            setTimeout(() => foo = 'baz', 500);
--------------------------------------------------------------------------------------------
            //export命令可以在模塊的任何位置,必須處於模塊頂層,如果在塊級作用域沒法靜態化會報錯。
            //報錯
            function foo() {
                export default 'bar' 
            }
            foo()
//main.js
//import命令
            import {a} from 'index.js';
            import {b} from 'index.js';
            import {c} from 'index.js';
            //等同於
            import {a,b,c} from 'index';//以上兩種寫法相同,import語句是獨生模式
--------------------------------------------------------------------------------------------
            import {a} from 'index';
            //報錯 變量a是隻讀的,可以改寫a的屬性
            var a = '1';
            //合法操作,但是其他模塊輸入讀到改寫後的值,不推薦使用難以查錯,可用於特殊場景路由控制等等
            var a.foo = 'ok';
--------------------------------------------------------------------------------------------
            //import 有提升效果,會提升到模塊頭部執行
            foo();
            import { foo } from 'my_module';//ok
--------------------------------------------------------------------------------------------
            //import 是靜態執行,不可以用變量和表達式,不能使用這些只有在運行時才能得到結果的語法結構。
            // 報錯
            import { 'f' + 'oo' } from 'my_module';
            // 報錯
            let module = 'my_module';
            import { foo } from module;
            // 報錯
            if (x === 1) {
              import { foo } from 'module1';
            } else {
              import { foo } from 'module2';
            }
//模塊使用整體加載
            //circle.js
            export function area(radius) {
              return Math.PI * radius * radius;
            }
            export function circumference(radius) {
              return 2 * Math.PI * radius;
            }
                    //index.js
            //逐一加載下面寫法
            import { area, circumference } from './circle';
            console.log('圓面積:' + area(4));
            console.log('圓周長:' + circumference(14));
            //使用整體加載,即用星號(*)指定一個對象,所有輸出值都加載在這個對象上面。
            import * as circle from './circle';
            console.log('圓面積:' + circle.area(4));
            console.log('圓周長:' + circle.circumference(14));
//export default 命令
            //方便加載,import命令可以爲該匿名函數指定任意名字。
            // export-default.js
            export default function () {
                console.log('foo');
            }
            // import-default.js
            import customer from './export-default';
            customer(); // 'foo'
--------------------------------------------------------------------------------------------
            //對應的import語句不需要使用大括號
            import customName from './index';
            customName(); // 'foo'
            //兩種寫法
            export default function () {
                console.log('foo');
            }
            //或者寫成
            function foo() {
                console.log('foo');
            }
            export default foo;
--------------------------------------------------------------------------------------------
            //export default 就是輸出一個叫做default的變量或方法
            // 正確
            export var a = 1;
            // 正確
            var a = 1;
            export default a;
            // 錯誤
            export default var a = 1;
            //export default命令輸出變量時,本質是將後面值,賦給default變量,所以可以直接將一個值寫在export default之後
            // 正確
            export default 42;
            // 報錯
            export 42;
--------------------------------------------------------------------------------------------
            //export default 允許用 as 任意命名,重命名爲 default 有效
            function add(x, y) {
                return x * y;
            }
            export {add as default};
            // 等同於
            export default add;
            //main.js 引用
            import { default as add } from './index';
            //等同於
            import add from './index';
--------------------------------------------------------------------------------------------
            //有了export default命令,import 可以同時輸入默認方法和其他接口
            //moudle.js
            export default function (obj) {
                
            }
            export function each(obj, iterator, context) {
                
            }
            export { each as forEach };
            //index.js
            import a, { each, forEach } form 'moudle';
--------------------------------------------------------------------------------------------
            //export default也可以用來輸出類
            // MyClass.js
            export default class {
                
            }
            // main.js
            import MyClass from 'MyClass';
            let o = new MyClass();
//import 和 export 複合寫法
            //export和import語句可以結合寫成一行。相當於對外轉發了接口,導致當前模塊不能直接使用foo和bar。
            export { foo, bar } from 'my_module';
            // 可以簡單理解爲
            import { foo, bar } from 'my_module';
            export { foo, bar };
--------------------------------------------------------------------------------------------
            //模塊的接口改名和整體輸出,也可以採用這種寫法。
            // 接口改名
            export { foo as myFoo } from 'my_module';
            // 整體輸出
            export * from 'my_module';
--------------------------------------------------------------------------------------------
            //默認接口的寫法如下。
            export { default } from 'foo';
--------------------------------------------------------------------------------------------
            //具名接口改爲默認接口的寫法如下。
            export { es6 as default } from './someModule';
            // 等同於
            import { es6 } from './someModule';
            export default es6;
--------------------------------------------------------------------------------------------
            //默認接口也可以改名爲具名接口。
            export { default as es6 } from './someModule';
--------------------------------------------------------------------------------------------
            //注意下面三種import語句,沒有對應的複合寫法。爲了做到形式的對稱,現在有提案。
            import * as someIdentifier from "someModule";//*號重命名整體加載
            import someIdentifier from "someModule";//默認接口重命名
            import someIdentifier, { namedIdentifier } from "someModule";//同時輸入默認方法和其他接口
//模塊繼承
            //circleplus模塊 繼承 circle模塊。
            // circle.js
            export function area(radius) {
              return Math.PI * radius * radius;
            }
            export function circumference(radius) {
              return 2 * Math.PI * radius;
            }
            export default function(){
                
            }
            // circleplus.js
            //這裏是複合寫法,export *,表示再輸出circle模塊所有屬性和方法。注意,export *命令會忽略circle模塊的default方法。然後,上面代碼又輸出了自定義的e變量和默認方法。
            export * from 'circle';
            export var e = 2.71828182846;
            export default function(x) {
              return Math.exp(x);
            }
            //也可以將circle的屬性或方法,改名後再輸出。將其改名爲circleArea。
            // circleplus.js
            export { area as circleArea } from 'circle';
            //加載模塊 import exp表示,將circleplus模塊的默認方法加載爲exp方法。
            // main.js
            import * as math from 'circleplus';
            import exp from 'circleplus';
            console.log(exp(math.e));
//跨模塊常量
            //const聲明的常量只在當前代碼塊有效。建一個專門的constants目錄,將各種常量寫在不同的文件裏面,保存在該目錄下。
            // constants/db.js
            export const db = {
              url: 'http://my.couchdbserver.local:5984',
              admin_username: 'admin',
              admin_password: 'admin password'
            };
            // constants/user.js
            export const users = ['root', 'admin', 'staff', 'ceo', 'chief', 'moderator'];
            //將這些文件輸出的常量,合併在index.js裏面。
            // constants/index.js
            export {db} from './db';
            export {users} from './users';
            //使用的時候,直接加載index.js就可以了。
            // script.js
            import {db, users} from './constants/index';

上面的總結,更加清晰明瞭,細節上還有很多地方需要注意,建議多敲代碼,明天再更、、、

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章