詳細(xì)全面的講解javascript中的export、import
在 JavaScript 中,export 和 import 是 ES6(ECMAScript 2015)引入的模塊系統(tǒng)核心語法,用于實(shí)現(xiàn)代碼的模塊化拆分、復(fù)用和依賴管理。它們允許將代碼分割到不同文件(模塊)中,每個模塊專注于特定功能,同時通過 export 暴露內(nèi)容、import 引入依賴,大幅提升了代碼的可維護(hù)性和可讀性。
一、模塊的基本概念
一個 JavaScript 文件就是一個模塊(module),模塊內(nèi)部的變量、函數(shù)、類等默認(rèn)是私有的,僅在當(dāng)前模塊內(nèi)可見。若要讓其他模塊使用這些內(nèi)容,必須通過 export 顯式暴露;其他模塊則通過 import 引入這些暴露的內(nèi)容。
模塊的核心特性:
- 自動運(yùn)行在嚴(yán)格模式(
"use strict")下,避免意外全局變量等問題。 - 模塊內(nèi)的頂層
this是undefined(非模塊腳本中this指向全局對象)。 - 模塊是單例的:同一模塊被多次導(dǎo)入時,僅執(zhí)行一次,后續(xù)導(dǎo)入復(fù)用第一次的結(jié)果。
- 模塊加載是異步的,按依賴順序執(zhí)行。
二、export:暴露模塊內(nèi)容
export 用于從當(dāng)前模塊向外暴露內(nèi)容(變量、函數(shù)、類等),供其他模塊導(dǎo)入。分為兩種方式:命名導(dǎo)出(named export)和默認(rèn)導(dǎo)出(default export)。
1. 命名導(dǎo)出(Named Export)
一個模塊可以有多個命名導(dǎo)出,每個導(dǎo)出都有明確的名稱,導(dǎo)入時必須使用相同的名稱(可重命名)。
語法形式:
直接在聲明時導(dǎo)出:
// 導(dǎo)出變量
export const name = "張三";
export let age = 20;
export const arr = [1, 2, 3];
// 導(dǎo)出函數(shù)
export function sum(a, b) {
return a + b;
}
// 導(dǎo)出類
export class Person {
constructor(name) {
this.name = name;
}
}先聲明后集中導(dǎo)出(更推薦,便于維護(hù)導(dǎo)出列表):
// 先聲明
const name = "張三";
function sum(a, b) {
return a + b;
}
class Person {}
// 集中導(dǎo)出(使用對象形式,鍵是導(dǎo)出名稱,值是要導(dǎo)出的內(nèi)容)
export { name, sum, Person };導(dǎo)出時重命名(避免名稱沖突):使用 as 關(guān)鍵字
const name = "張三";
export { name as userName }; // 導(dǎo)出時將 name 重命名為 userName2. 默認(rèn)導(dǎo)出(Default Export)
一個模塊只能有一個默認(rèn)導(dǎo)出,通常用于導(dǎo)出模塊的“主要內(nèi)容”(比如一個核心函數(shù)或類)。導(dǎo)入時可以自定義名稱,無需與導(dǎo)出名稱一致。
語法形式:
直接導(dǎo)出(無需名稱):
// 導(dǎo)出默認(rèn)函數(shù)
export default function(a, b) {
return a + b;
}
// 導(dǎo)出默認(rèn)類
export default class {
constructor() {}
}
// 導(dǎo)出默認(rèn)對象
export default {
name: "張三",
age: 20
};先聲明后導(dǎo)出(需顯式指定 default):
const mainFunction = () => { /* ... */ };
export default mainFunction; // 默認(rèn)導(dǎo)出 mainFunction
注意: 默認(rèn)導(dǎo)出本質(zhì)上是“名稱為 default 的命名導(dǎo)出”,只是語法上簡化了。
3. 混合導(dǎo)出
一個模塊可以同時包含命名導(dǎo)出和默認(rèn)導(dǎo)出:
// 命名導(dǎo)出
export const version = "1.0.0";
// 默認(rèn)導(dǎo)出
export default function core() { /* 核心功能 */ }三、import:導(dǎo)入模塊內(nèi)容
import 用于從其他模塊導(dǎo)入已導(dǎo)出的內(nèi)容,語法需與對應(yīng)模塊的 export 方式匹配。
1. 導(dǎo)入命名導(dǎo)出的內(nèi)容
需使用大括號 {} 包裹導(dǎo)出時的名稱,且名稱必須與導(dǎo)出時一致(可通過 as 重命名)。
基本語法:
// 導(dǎo)入 module.js 中的命名導(dǎo)出
import { name, sum, Person } from './module.js';
// 使用導(dǎo)入的內(nèi)容
console.log(name); // 張三
console.log(sum(1, 2)); // 3
const p = new Person();重命名導(dǎo)入(避免沖突):
// 導(dǎo)入時將 sum 重命名為 add
import { sum as add } from './module.js';
console.log(add(1, 2)); // 32. 導(dǎo)入默認(rèn)導(dǎo)出的內(nèi)容
無需大括號,可自定義名稱(推薦與模塊功能相關(guān)的名稱)。
基本語法:
// 導(dǎo)入 module.js 的默認(rèn)導(dǎo)出(假設(shè)導(dǎo)出的是一個函數(shù)) import calculate from './module.js'; // calculate 是自定義名稱 calculate(1, 2); // 調(diào)用默認(rèn)導(dǎo)出的函數(shù)
3. 同時導(dǎo)入默認(rèn)導(dǎo)出和命名導(dǎo)出
// 導(dǎo)入默認(rèn)導(dǎo)出(core)和命名導(dǎo)出(version)
import core, { version } from './module.js';
// 使用
core(); // 調(diào)用默認(rèn)導(dǎo)出的核心函數(shù)
console.log(version); // 1.0.04. 整體導(dǎo)入(命名空間導(dǎo)入)
將模塊中所有導(dǎo)出(包括命名導(dǎo)出和默認(rèn)導(dǎo)出)作為一個對象的屬性導(dǎo)入,默認(rèn)導(dǎo)出會作為 default 屬性。
語法:
// 將 module.js 中所有導(dǎo)出合并為一個 module 對象 import * as module from './module.js'; // 使用命名導(dǎo)出的內(nèi)容 console.log(module.name); module.sum(1, 2); // 使用默認(rèn)導(dǎo)出的內(nèi)容(默認(rèn)導(dǎo)出會被放在 default 屬性中) module.default();
5. 僅執(zhí)行模塊(不導(dǎo)入內(nèi)容)
如果模塊僅需要執(zhí)行副作用(如初始化操作),無需導(dǎo)入其內(nèi)容,可直接導(dǎo)入:
import './init.js'; // 執(zhí)行 init.js 中的代碼,但不導(dǎo)入任何內(nèi)容
四、動態(tài)導(dǎo)入(Dynamic Import)
ES2020 引入了動態(tài)導(dǎo)入語法 import(),與靜態(tài) import 不同,它是一個函數(shù),返回一個 Promise,支持在運(yùn)行時按需加載模塊(適合代碼分割、懶加載)。
語法:
// 動態(tài)導(dǎo)入 module.js,返回 Promise
import('./module.js')
.then((module) => {
// 模塊加載成功后使用
console.log(module.name); // 訪問命名導(dǎo)出
module.default(); // 訪問默認(rèn)導(dǎo)出
})
.catch((err) => {
console.error('模塊加載失敗', err);
});配合 async/await 使用(更簡潔):
async function loadModule() {
try {
const module = await import('./module.js');
console.log(module.name);
} catch (err) {
console.error(err);
}
}
loadModule();
應(yīng)用場景:
- 路由懶加載(如 React Router、Vue Router 中按需加載組件)。
- 根據(jù)條件加載不同模塊(如不同環(huán)境加載不同配置)。
- 減少初始加載資源體積,提升性能。
五、模塊路徑規(guī)則
import 后的模塊路徑需遵循以下規(guī)則:
相對路徑:導(dǎo)入本地模塊時,必須以 ./(當(dāng)前目錄)或 ../(父目錄)開頭,且通常需要包含文件擴(kuò)展名(如 .js)。
import { sum } from './utils/math.js'; // 正確
import { sum } from 'utils/math.js'; // 錯誤(缺少 ./)
絕對路徑:從項(xiàng)目根目錄或 CDN 導(dǎo)入(較少用):
import { sum } from '/src/utils/math.js'; // 項(xiàng)目根目錄
import { sum } from 'https://cdn.example.com/utils.js'; // CDN
第三方模塊:導(dǎo)入 npm 安裝的包時,直接寫包名(無需路徑):
import React from 'react'; // 導(dǎo)入 react 包 import axios from 'axios'; // 導(dǎo)入 axios 包
六、使用環(huán)境要求
import 和 export 屬于 ES 模塊語法,使用時需注意環(huán)境支持:
- 瀏覽器環(huán)境:
- 需在
<script>標(biāo)簽中添加type="module"屬性,聲明為模塊腳本:
- 需在
<script type="module"> import { sum } from './math.js'; console.log(sum(1, 2)); </script>- 本地開發(fā)時需通過服務(wù)器(如
localhost)訪問,直接打開本地文件(file://協(xié)議)會因跨域限制報(bào)錯。
- 本地開發(fā)時需通過服務(wù)器(如
- Node.js 環(huán)境:
- 默認(rèn)支持 CommonJS 模塊(
require/module.exports),若使用 ES 模塊,需: - 將文件擴(kuò)展名改為
.mjs; - 或在
package.json中添加"type": "module"。
- 默認(rèn)支持 CommonJS 模塊(
七、常見問題與注意事項(xiàng)
- 默認(rèn)導(dǎo)出 vs 命名導(dǎo)出:
- 默認(rèn)導(dǎo)出適合模塊的“主要功能”(一個模塊一個),導(dǎo)入時名稱可自定義。
- 命名導(dǎo)出適合模塊的“輔助功能”(多個),導(dǎo)入時名稱必須匹配(可重命名)。
- 重復(fù)導(dǎo)出:同一名稱不能重復(fù)命名導(dǎo)出,否則報(bào)錯。
- 導(dǎo)入不可變:導(dǎo)入的內(nèi)容是“只讀視圖”,不能直接修改(但對象屬性可改):
// module.js export let count = 0; // 導(dǎo)入后 import { count } from './module.js'; count = 1; // 報(bào)錯(只讀)- 循環(huán)依賴:模塊之間循環(huán)導(dǎo)入(A 導(dǎo)入 B,B 導(dǎo)入 A)是允許的,但需注意執(zhí)行順序可能導(dǎo)致未定義的值。
- 靜態(tài)分析:靜態(tài)
import必須放在模塊頂層(不能在if、函數(shù)等塊級作用域中),動態(tài)import()則可以。
總結(jié)
export 和 import 是 JavaScript 模塊化的核心,通過它們可以實(shí)現(xiàn)代碼的拆分、復(fù)用和依賴管理:
export分為命名導(dǎo)出(多個)和默認(rèn)導(dǎo)出(一個),用于暴露模塊內(nèi)容。import需與導(dǎo)出方式匹配,支持命名導(dǎo)入、默認(rèn)導(dǎo)入、整體導(dǎo)入等。- 動態(tài)
import()支持按需加載,適合性能優(yōu)化。
掌握這些語法能幫助你寫出更清晰、可維護(hù)的大型 JavaScript 應(yīng)用。
到此這篇關(guān)于詳細(xì)全面的解說javascript中的export、import的文章就介紹到這了,更多相關(guān)js export、import內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
微信小程序?qū)崿F(xiàn)點(diǎn)擊頁面出現(xiàn)文字
這篇文章主要介紹了微信小程序?qū)崿F(xiàn)點(diǎn)擊頁面出現(xiàn)文字,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下2020-09-09
JavaScript實(shí)現(xiàn)頁面跳轉(zhuǎn)的方式匯總
在動手做網(wǎng)站時,不可避免的會碰到頁面跳轉(zhuǎn)的問題,新頁面是在當(dāng)前頁面打開呢,還是在新窗口打開呢,是不是需要依據(jù)參數(shù)進(jìn)行跳轉(zhuǎn)呢或者要經(jīng)過用戶確認(rèn)后再跳轉(zhuǎn)呢,等等很多種情況,下面我們來看下常用的一些JS實(shí)現(xiàn)頁面跳轉(zhuǎn)的方式例子,需要的朋友可以參考下2016-05-05
js 分頁全選或反選標(biāo)識實(shí)現(xiàn)代碼
分頁全選或反選標(biāo)識 對多選按鈕操作。 批量全選添加、批量移除。 行單選添加、移除。 分頁之后(全選或不選)狀態(tài)標(biāo)識依然存在2011-08-08
CodeMirror實(shí)現(xiàn)代碼對比功能(插件react vue)
這篇文章主要介紹了CodeMirror實(shí)現(xiàn)代碼對比功能,用到的插件有vue或者react都需要這一步且同樣的下載方式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05

