<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          深入了解 Export 和 import

          共 8450字,需瀏覽 17分鐘

           ·

          2021-03-10 10:20

          深入了解 export 和 import

          Export和import指令有幾種語法變體。

          在上一篇文章中,我們看到了一個簡單的用法,現(xiàn)在讓我們探討更多的示例。

          export 之前申明

          我們可以將任何聲明(無論是變量、函數(shù)還是類)置于export之前,從而將其標(biāo)記為導(dǎo)出。

          例如,這里所有的導(dǎo)出都是有效的:

          // export an array
          export let months = ['Jan''Feb''Mar','Apr''Aug''Sep''Oct''Nov''Dec'];

          // export a constant
          export const MODULES_BECAME_STANDARD_YEAR = 2015;

          // export a class
          export class User {
            constructor(name) {
              this.name = name;
            }
          }

          請注意,在類或函數(shù)之前導(dǎo)出并不會使其成為函數(shù)表達式。它仍然是一個函數(shù)聲明,盡管已經(jīng)導(dǎo)出。

          大多數(shù)JavaScript風(fēng)格指南不建議在函數(shù)和類聲明后使用分號。

          這就是為什么在導(dǎo)出類和導(dǎo)出函數(shù)的結(jié)尾不需要分號的原因:

          export function sayHi(user{
            alert(`Hello, ${user}!`);
          }  // no ; at the end

          除聲明外的 export

          此外,我們可以把出口分開。

          這里我們首先聲明,然后導(dǎo)出:

          // ?? say.js
          function sayHi(user{
            alert(`Hello, ${user}!`);
          }

          function sayBye(user{
            alert(`Bye, ${user}!`);
          }

          export {sayHi, sayBye}; // a list of exported variables

          Import *

          通常,我們把要導(dǎo)入的內(nèi)容放在花括號import{…},像這樣:

          // ?? main.js
          import {sayHi, sayBye} from './say.js';

          sayHi('John'); // Hello, John!
          sayBye('John'); // Bye, John!

          但如果有很多東西需要導(dǎo)入,我們可以使用import * as 將所有東西作為對象導(dǎo)入,例如:

          // ?? main.js
          import * as say from './say.js';

          say.sayHi('John');
          say.sayBye('John');

          乍一看,“導(dǎo)入所有內(nèi)容”似乎是一件很酷的事情,簡單說來,為什么我們要明確地列出我們需要導(dǎo)入的內(nèi)容呢?

          嗯,有幾個原因。

          現(xiàn)代構(gòu)建工具(webpack和其他工具)將模塊捆綁在一起,并對它們進行優(yōu)化,以加速加載和刪除未使用的內(nèi)容。

          比如說,我們在我們的項目中添加了一個帶有許多函數(shù)的第三方庫say.js:

          // ?? say.js
          export function sayHi({ ... }
          export function sayBye({ ... }
          export function becomeSilent({ ... }

          現(xiàn)在,如果我們在項目中只使用say.js中的一個函數(shù):

          // ?? main.js
          import {sayHi} from './say.js';

          然后優(yōu)化器將看到這一點,并從捆綁代碼中刪除其他函數(shù),從而使構(gòu)建更小。這被稱為“tree-shaking”。

          顯式列出要導(dǎo)入的內(nèi)容會給出更短的名稱:sayHi()而不是say.sayHi()。

          顯式的導(dǎo)入列表可以更好地概述代碼結(jié)構(gòu):使用了什么和在哪里使用。它使代碼支持和重構(gòu)更容易。

          Import “as”

          我們還可以使用as在不同的名稱下導(dǎo)入。

          例如,為了簡潔起見,讓我們將sayHi導(dǎo)入到本地變量hi中,并將sayBye作為bye導(dǎo)入:

          // ?? main.js
          import {sayHi as hi, sayBye as bye} from './say.js';

          hi('John'); // Hello, John!
          bye('John'); // Bye, John!

          Export “as”

          導(dǎo)出也有類似的語法。

          讓我們導(dǎo)出hi和bye函數(shù):

          // ?? say.js
          ...
          export {sayHi as hi, sayBye as bye};

          hi和bye是對外來者的正式稱呼,用于進口產(chǎn)品:

          // ?? main.js
          import * as say from './say.js';

          say.hi('John'); // Hello, John!
          say.bye('John'); // Bye, John!

          Export default

          在實踐中,主要有兩種模塊。

          包含庫和函數(shù)包的模塊,如上面的say.js

          聲明單個實體的模塊,例如,模塊User. js只導(dǎo)出類User

          大多數(shù)情況下,第二種方法是首選的,這樣每個“東西”都駐留在自己的模塊中。

          當(dāng)然,這需要很多文件,因為所有東西都需要自己的模塊,但這根本不是問題。實際上,如果文件的名稱很好,并且被結(jié)構(gòu)化到文件夾中,代碼導(dǎo)航就會變得更容易。

          模塊提供了一個特殊的export default (" the default export ")語法,使"每個模塊一件事"的方式看起來更好。

          export default放在要導(dǎo)出的實體之前:

          // ?? user.js
          export default class User // just add "default"
            constructor(name) {
              this.name = name;
            }
          }

          每個文件可能只有一個默認的導(dǎo)出。

          然后不帶大括號導(dǎo)入:

          // ?? main.js
          import User from './user.js'// not {User}, just User

          new User('John');

          不帶大括號的導(dǎo)入看起來更好。開始使用模塊時的一個常見錯誤是完全忘記花括號。記住,import對命名的導(dǎo)出需要花括號而默認的導(dǎo)出不需要花括號。


          Named export           Default export
          export class User {...} export default class User {...}
          import {User} from ... import User from ...

          從技術(shù)上講,我們可能在一個模塊中同時有默認導(dǎo)出和命名導(dǎo)出,但在實踐中,人們通常不會將它們混合在一起。模塊有命名的exports或默認的exports。

          由于每個文件最多可能有一個默認導(dǎo)出,因此導(dǎo)出的實體可能沒有名稱。

          例如,這些都是完全有效的默認導(dǎo)出:

          export default class // no class name
            constructor() { ... }
          }
          export default function(user// no function name
            alert(`Hello, ${user}!`);
          }
          // export a single value, without making a variable
          export default ['Jan''Feb''Mar','Apr''Aug''Sep''Oct''Nov''Dec'];
          export class // Error! (non-default export needs a name)
            constructor() {}
          }

          The “default” name

          在某些情況下,default關(guān)鍵字用于引用默認的導(dǎo)出。

          例如,將一個函數(shù)與它的定義分開導(dǎo)出:

          function sayHi(user{
            alert(`Hello, ${user}!`);
          }

          // same as if we added "export default" before the function
          export {sayHi as default};

          或者,另一種情況,讓我們說一個模塊user.js導(dǎo)出了一個主要的“默認”東西,以及一些命名的東西(很少有這種情況,但它發(fā)生了):

          // ?? user.js
          export default class User {
            constructor(name) {
              this.name = name;
            }
          }

          export function sayHi(user{
            alert(`Hello, ${user}!`);
          }

          下面是如何導(dǎo)入一個指定的默認導(dǎo)出:

          // ?? main.js
          import {default as User, sayHi} from './user.js';

          new User('John');

          最后,如果將所有東西*作為對象導(dǎo)入,那么默認屬性就是默認的export:

          // ?? main.js
          import * as user from './user.js';

          let User = user.default; // the default export
          new User('John');

          A word against default exports

          命名導(dǎo)出是顯式的。它們精確地命名了它們導(dǎo)入的內(nèi)容,所以我們從它們那里得到了這些信息;這是件好事。

          命名導(dǎo)出強制我們在導(dǎo)入時使用正確的名稱:

          import {User} from './user.js';
          // import {MyUser} won't work, the name must be {User}

          而對于默認導(dǎo)出,我們總是在導(dǎo)入時選擇名稱:

          import User from './user.js'// works
          import MyUser from './user.js'// works too
          // could be import Anything... and it'll still work

          因此,團隊成員可能會使用不同的名稱來導(dǎo)入相同的東西,這不是很好。

          通常,為了避免這種情況并保持代碼的一致性,有一個規(guī)則,即導(dǎo)入的變量應(yīng)該對應(yīng)于文件名,

          例如:

          import User from './user.js';
          import LoginForm from './loginForm.js';
          import func from '/path/to/func.js';
          ...

          Re-export

          " Re-export "語法從…允許導(dǎo)入并立即導(dǎo)出(可能是另一個名稱),像這樣:

          export {sayHi} from './say.js'// re-export sayHi

          export {default as User} from './user.js'// re-export default

          為什么需要這樣做?讓我們來看一個實際的用例。

          想象一下,我們正在編寫一個“包”:一個包含大量模塊的文件夾,其中一些功能被導(dǎo)出到外部(像NPM這樣的工具允許我們發(fā)布和分發(fā)這些包,但我們不必使用它們),而許多模塊只是“助手”,供其他包模塊內(nèi)部使用。

          文件結(jié)構(gòu)可能是這樣的:

          auth/
              index.js
              user.js
              helpers.js
              tests/
                  login.js
              providers/
                  github.js
                  facebook.js
                  ...

          我們希望通過單個入口點公開包的功能。

          換句話說,想要使用我們的包的人,應(yīng)該只從“主文件”auth/index.js導(dǎo)入。

          是這樣的:

          import {login, logout} from 'auth/index.js'

          “主文件”auth/index.js導(dǎo)出了我們想在包中提供的所有功能。

          其思想是,外部的人,也就是使用我們包的其他程序員,不應(yīng)該干涉它的內(nèi)部結(jié)構(gòu),搜索我們包文件夾中的文件。我們只導(dǎo)出auth/index.js中必要的部分,其余部分則不被窺探。

          由于實際導(dǎo)出的功能分散在包中,我們可以將其導(dǎo)入auth/index.js并從中導(dǎo)出:

          // ?? auth/index.js

          // import login/logout and immediately export them
          import {login, logout} from './helpers.js';
          export {login, logout};

          // import default as User and export it
          import User from './user.js';
          export {User};
          ...

          現(xiàn)在我們包的用戶可以從“auth/index.js”中導(dǎo)入{login}。

          語法export…從…只是這種進出口的縮寫:

          // ?? auth/index.js
          // re-export login/logout
          export {login, logout} from './helpers.js';

          // re-export the default export as User
          export {default as User} from './user.js';
          ...

          出口的顯著差異是……與導(dǎo)入/導(dǎo)出相比,重新導(dǎo)出的模塊在當(dāng)前文件中不可用。所以在上面的auth/index.js示例中,我們不能使用重新導(dǎo)出的登錄/注銷函數(shù)。

          Re-exporting the default export

          155/5000 重新導(dǎo)出時,默認導(dǎo)出需要單獨處理。

          假設(shè)我們有User .js和導(dǎo)出默認類User,并想重新導(dǎo)出它:

          // ?? user.js
          export default class User {
            // ...
          }
          export * from './user.js'// to re-export named exports
          export {defaultfrom './user.js'// to re-export the default export

          這種重新導(dǎo)出默認導(dǎo)出的奇怪現(xiàn)象是一些開發(fā)人員不喜歡默認導(dǎo)出而更喜歡命名導(dǎo)出的原因之一

          瀏覽 62
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日韩无码成人影片 | 色婷婷五月天小说 | 青娱乐偷拍 | 欧美高清爱爱视频 | 久操久操久操 |