<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      ES6中的export和import

      1、ES6中的模塊加載

      ES6 模塊是編譯時加載,編譯時就能確定模塊的依賴關系,以及輸入和輸出的變量,相比于CommonJS 和 AMD 模塊都只能在運行時確定輸入輸出變量的加載效率要高。

      1.1、嚴格模式

      ES6 的模塊自動采用嚴格模式,不管你有沒有在模塊頭部加上 "use strict"; 語句

      嚴格模式主要有以下限制。

      • 變量必須聲明后再使用
      • 函數的參數不能有同名屬性,否則報錯
      • 不能使用with語句
      • 不能對只讀屬性賦值,否則報錯
      • 不能使用前綴 0 表示八進制數,否則報錯
      • 不能刪除不可刪除的屬性,否則報錯
      • 不能刪除變量delete prop,會報錯,只能刪除屬性delete global[prop]
      • eval不會在它的外層作用域引入變量
      • evalarguments不能被重新賦值
      • arguments不會自動反映函數參數的變化
      • 不能使用arguments.callee
      • 不能使用arguments.caller
      • 禁止this指向全局對象
      • 不能使用fn.callerfn.arguments獲取函數調用的堆棧
      • 增加了保留字(比如protectedstaticinterface

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

       

      2、export 命令

      一個模塊就是一個獨立的文件,該文件內部的所有變量,外部都無法獲取。如果你希望外部能夠讀取模塊內部的某個變量,就必須使用export關鍵字輸出該變量。

      如果你沒引入變量,即使你引入執行了該模塊你仍然無法獲取模塊的變量。

      // a.js
      let str = 'aaaa'
      
      //b.js
      import './a.js'     //相當于執行了 a.js 文件代碼
      console.log(str);   //報錯  str is not defined    

      export命令可以出現在模塊的任何位置,但必須處于模塊頂層,如果處于塊級作用域內,就會報錯(即不能包含在任何代碼塊中,比如不能在函數體內)。

      export 命令有多種寫法,下面將逐一介紹:

       

      2.1、export 后面直接加聲明語句(export var a = '')

      // a.js
      export var firstName = 'Michael';
      export var lastName = 'Jackson';
      export var year = 1958;
      
      export function fn(x, y) {
        return x * y;
      };
      //此時的導入import語法
      import {firstName, lastName, year} from './a.js'

       

      2.2、使用大括號指定輸出(export {},常用)

      這是推薦使用的輸出方式,因為這樣就可以在腳本尾部,一眼看清楚輸出了哪些變量。

      // a.js
      var firstName = 'Michael';
      var lastName = 'Jackson';
      var year = 1958;
      
      export { firstName, lastName, year };
      //此時的導入語法
      import {firstName, lastName, year} from './a.js'

      export命令后面,使用大括號指定所要輸出的一組變量與 export 直接加聲明語句是等價的,但是應該優先考慮使用這種寫法。

       

      2.3、as關鍵字重命名(export {a as newName})

      通常情況下,export輸出的變量就是本來的名字,但是可以使用as關鍵字重命名。as 關鍵字后面的變量名是輸出的名字。

      let str = 'aaa'
      function v1() { ... }
      function v2() { ... }
      
      export {
        str as str2, 
        v1 as streamV1,
        v2 as streamV2,
        v2 as streamLatestVersion
      };
      //此時的導入語法
      //此時不能用之前的名字導入,只能用重命名后的名字導入
      import {str2, streamV1, streamV2, streamLatestVersion} from "./index";

      使用重命名,同一個變量可以用不同的名字輸出兩次,這樣在外部可以用不同的名字引入該變量。

       

      2.4、export default(常用)

      使用前面的語法進行輸出時,輸入的用戶必須得知道輸出的變量名才能使用,有時這并不怎么方便。使用export default命令可以為模塊指定默認輸出,用戶可以為輸入的變量起一個任意的名字,就不需要提前知道輸出的變量名便可上手使用了。

      使用 default 語法,后面可以直接跟變量名,這點跟其他輸出語法不一樣。

      // a.js 輸出
      export default function foo() {
        console.log('foo');
      }
      
      //或者寫成下面兩種都可以
      export default function() {
        console.log('foo');
      }

      function foo() { console.log('foo'); } export default foo;
      //此時的導入語法
      import fn from './export-default';
      fn();

      上面代碼的import命令,可以用任意名稱指向a.js輸出的方法,這時就不需要知道原模塊輸出的函數名。default 命令后面的變量名在模塊外部是無效的,同匿名函數輸出的形式一致。

      注意,使用 export default 命令輸出的模塊,import命令后面不需要大括號。一個模塊只能有一個默認輸出,因此export default命令只能使用一次。所以,import命令后面才不用加大括號,因為只可能唯一對應export default命令。

       可以用 default 導出一個對象來導出多個值: 

      //a.js
      export default {
        a () {
           console.log('aaa')
        },
        b () {
          console.log('bbb')
        },
        c: 'ccc'
      }
      //此時的導入語法
      import obj from './a.js'
      obj.a();    //aaa
      console.log(obj.c)  //ccc
      
      //注意,此時不能用大括號導入,下面會報錯
      import {a, b, c} from './a.js'   //報錯

       

      2.5、export 的錯誤語法

      export命令不能直接輸出變量,因為變量的值必須在運行階段才能確定,而 export 命令的輸出是在編譯階段就已經輸出。

      // 報錯
      export 1;
      
      // 報錯
      var m = 1;
      export m;
      
      // 報錯
      function f() {}
      export f;


      export 命令規定的是對外的接口,必須與模塊內部的變量建立一一對應關系。

      如何理解這句話?(可以參考:https://www.imooc.com/wenda/detail/458477

      export 1  ,這里輸出的是一個值 1,沒有與任何模塊內部變量建立聯系,所以直接報錯。

      var m = 1;  export m;    這里看起來就像是輸出了一個變量m作為對外的接口,我們可能會認為 m 這個變量被輸出到模塊外被使用,并且與模塊內的 m 產生了引用的關系。然而現實情況是,變量m在模塊中作為一個變量存在,但是通過export導出m時,被導出的只有m的值 1,所以同樣不與內部變量產生聯系,于是報錯。

      這跟函數的傳參是一個道理:

      let x = 1;                 //聲明變量
      const foo=(x)=>{x=2};    //聲明一個函數
      foo(x)                   //傳入x
      console.log(x)           //    1

      上面代碼中,變量 x 作為 foo 的參數,只把變量 x 的值傳入 foo,x 只作為數值的載體,函數內部 x 并沒有與變量 x 產生直接聯系。只是復制了變量 x 的值(這種復制值然后再使用的形式與CommonJS加載模式類似)。

      2.5.1、export default 的錯誤語法

      export default命令其實只是輸出一個叫做default的變量,所以它后面不能跟變量聲明語句。

      // 錯誤
      export default var a = 1;

       同樣地,因為export default命令的本質是將后面的值,賦給default變量,所以可以直接將一個值寫在export default之后。

      // 正確
      export default 42;
      
      // 報錯
      export 42;

       

      2.6、export 中 default 和其他輸出結合使用

      export 中 default 是可以和其他輸出結合使用的

      // a.js 輸出  下面將輸出三個函數
      export default function (obj) {
      }
      export function each(obj, iterator, context) {
      }
      export { each as forEach };
      
      // b.js 輸入  這里可以分別輸入三個值
      import  aaa, { each, forEach } from 'a.js';

       

      3、import 命令

      使用export命令定義了模塊的對外接口以后,其他 JS 文件就可以通過import命令加載這個模塊。

      import命令輸入的變量都是只讀的,不可以在加載后修改引入的變量。但如果引入的變量是對象的話,可以修改對象的屬性,但非常不推薦使用。

      import {obj} from './a.js'
      obj = {}; // Syntax Error : 'obj' is read-only;

      上面代碼中,對引入變量重新賦值就會報錯。但是,如果a是一個對象,改寫a的屬性是允許的,但非常不推薦修改引入的變量,因為其他引入的模塊也可以讀到改寫后的值,這種寫法很難查錯,所以凡是輸入的變量,都當作完全只讀,輕易不要改變它的屬性。

       

      import命令具有提升效果,會提升到整個模塊的頭部,首先執行,因為 import 命令是編譯階段執行的,在代碼運行之前。

      foo();
      import { foo } from 'my_module';       //這里不會報錯,因為import的執行早于foo的調用

       

      import語句會執行所加載的模塊,因此可以有下面的寫法。如果多次重復執行同一句import語句,那么只會執行一次模塊的文件代碼,而不會執行多次。也就是說import語句是 Singleton 模式。

      import 'a.js';    //這里僅僅執行lodash模塊,但是不輸入任何值,所以并不能使用 a.js 里面定義的變量
      
      //下面代碼加載了兩次lodash,但是只會執行一次。
      import 'lodash';
      import 'lodash';
      
      import { foo } from 'my_module';
      import { bar } from 'my_module';
      // 等同于
      import { foo, bar } from 'my_module';

       

      目前階段,通過 Babel 轉碼,require命令和import命令可以寫在同一個模塊里面,但是最好不要這樣做。因為import在靜態解析階段執行,所以它是一個模塊之中最早執行的。

      //下面的代碼可能不會得到預期結果,因為import將會于require之前執行
      require('core-js/modules/es6.symbol');
      require('core-js/modules/es6.promise');
      import React from 'React';

       

      import 的語法有多種,下面將逐一介紹:

      3.1、import {} from 'xxx.js'

      // a.js 輸出
      var firstName = 'Michael';
      var lastName = 'Jackson';
      export { firstName, lastName};
      
      // b.js 輸入
      import { firstName, lastName} from './a.js';
      //引入后可以直接使用
      console.log(firstName,lastName)

       

      3.2、import {a as newName} from 'xxx.js'

      如果想為輸入的變量重新取一個名字可以使用as關鍵字,將輸入的變量重命名。as 關鍵字后面的是輸入的變量名,即你想使用的名字

      import { firstName as newName } from './a.js';

       

      3.3、import * as newName from 'xxx.js'(模塊的整體加載)

      除了指定加載某個輸出值,還可以使用整體加載,即加載模塊的整個輸出對象。用星號(*)指定一個對象,所有輸出值都將加載在這個對象上面。

      // a.js
      export var area = 'aaa'
      export function circumference(radius) {
        return 2 * Math.PI * radius;
      }
      
      //b.js
      import * as newObj from './circle';
      console.log(newObj .area);
      console.log(newObj .circumference(14));

      不允許修改整體加載的對象

      import * as circle from './circle';
      // 下面兩行都是不允許的
      circle.foo = 'hello';
      circle.area = function () {};

       

      3.4、import 的錯誤語法

      import不能使用表達式和變量,因為 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';
      }

       

      4、export 和 import 的復合寫法

      如果在一個模塊之中,先輸入后輸出同一個模塊,import語句可以與export語句寫在一起。

      export { foo, bar } from 'my_module';
      
      // 可以簡單理解為
      import { foo, bar } from 'my_module';
      export { foo, bar };

      但需要注意的是,寫成一行以后,foobar實際上并沒有被導入當前模塊,只是相當于對外轉發了這兩個接口,導致當前模塊不能直接使用foobar

      其他的復合寫法:

      // 接口改名輸出
      export { foo as myFoo } from 'my_module';
      //等同于
      import {foo} from 'mu_module'
      export {foo as myFoo}
      
      // 整體輸出
      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';

       

      5、ES6的循環引用

      ES6 遇到循環引用時并不會報錯,ES6 遇到引用會先去執行引用文件的代碼,如果某文件已經在執行了,則不會再去重復執行該文件,由此并不會形成死循環的現象。

      假設引用了 a.js 文件,然后 a.js 引用了 b.js,b.js 又引用了 a.js 文件,由此形成了循環引用,代碼如下:

      import a from './a.js'

      a.js 文件內容:

      console.log('進入a.js');
      import b from './b.js'
      console.log('從a引用的b模塊', b)
      console.log('引用b之后')
      export default '我是a模塊'

      b.js 文件內容:

      console.log('進入b.js')
      import a from './a.js'
      console.log('從b引用的a模塊', a)
      console.log('引用a之后')
      export default '我是b模塊'

      執行結果:

      分析如下:

      1. 由于 import命令具有提升效果,會提升到整個模塊的頭部,所以首先執行 b.js ;
      2. b.js 的第二行加載 a.js,這時由于 a.js 已經開始執行,所以不會重復執行 a.js,而是繼續執行b.js 后面內容
      3. b.js 第三行打印變量 a,這時 a.js 還沒有執行完,取不到 a 的值,因此打印出來undefined
      4. b.js 執行完后回來執行 a.js,第二行打印變量 b,由于 b.js 已經執行完了,所以可以正常打印該值

      可參考:https://blog.csdn.net/m0_56132701/article/details/134464210

       

      6、關于import{}會引入所有組件的問題

      我們在使用各大 UI 組件庫時都會被介紹到為了避免引入全部文件,請使用 babel-plugin-component等babel 插件。

      import { Button, Select } from 'element-ui'

      由前文可知 import 會先轉換為 commonjs, 即

      var a = require('element-ui');
      var Button = a.Button;
      var Select = a.Select;

      var a = require('element-ui');這個過程就會將所有組件都引入進來了。
      所以 babel-plugin-component就做了一件事,將 import { Button, Select } from 'element-ui'轉換成了

      import Button from 'element-ui/lib/button'
      import Select from 'element-ui/lib/select'

      即使轉換成了 commonjs 規范,也只是引入自己這個組件的js,將引入量減少到最低。
      所以我們會看到幾乎所有的UI組件庫的目錄形式都是

      |-lib
      ||--component1
      ||--component2
      ||--component3
      |-index.common.js
      

      index.common.js 給 import element from 'element-ui' 這種形式調用全部組件。lib 下的各組件用于按需引用。

      這里解釋了為什么經常在各大UI組件引用的文檔上會看到說明 import { button } from 'xx-ui' 這樣會引入所有組件內容,需要添加額外的 babel 配置,比如 babel-plugin-component

      參考:http://www.rzrgm.cn/jiaoshou/p/15988575.html

       

      posted @ 2019-08-07 03:03  wenxuehai  閱讀(2442)  評論(1)    收藏  舉報
      //右下角添加目錄
      主站蜘蛛池模板: 亚洲欧洲一区二区精品| 丝袜美腿一区二区三区| 激情综合色综合啪啪开心| 久久热精品视频在线视频| 九九热精品在线视频免费| 亚洲AV成人无码久久精品四虎| 亚洲av成人一区在线| 午夜精品区| 特黄三级又爽又粗又大| 精品一卡2卡三卡4卡乱码精品视频| 五月天中文字幕mv在线| AV免费播放一区二区三区| 丰满无码人妻热妇无码区| 人妻出轨av中文字幕| 日日噜噜夜夜狠狠视频| 麻豆国产va免费精品高清在线| 国产精品线在线精品| 一区二区三区av天堂| 97精品国产91久久久久久久| 精品国产91久久粉嫩懂色| 婷婷丁香五月深爱憿情网| 亚洲一区二区三区丝袜| 久久综合色一综合色88| 91无码人妻精品一区二区蜜桃| 久久精品蜜芽亚洲国产av| 蜜臀视频在线观看一区二区| 中文字幕乱码中文乱码毛片| 成人av久久一区二区三区| 午夜成年男人免费网站| 中国老熟妇自拍hd发布| 大又大又粗又硬又爽少妇毛片| 亚洲中文久久久精品无码| 人妻夜夜爽天天爽一区| 国产超碰人人爽人人做人人添| 国产明星精品无码AV换脸| 崇义县| 国产三级国产精品久久成人| 久久69国产精品久久69软件| 成人一区二区不卡国产| 毛片网站在线观看| 国产中文字幕久久黄色片|