JavaScript 模块化规范

179次阅读
没有评论

共计 2962 个字符,预计需要花费 8 分钟才能阅读完成。

概述

什么是模块化

  • 将程序文件依据一定规则 拆分 成多个文件,这种编码方式就是模块化的编码方式
  • 拆分出来的 每个文件就是一个模块,模块中的数据都是私有的,模块之间互相隔离
  • 同时也能通过一些手段,把模块内的指定数据“交出去”,供其他模块使用

为什么需要模块化

随着应用的复杂度越来越高,其代码量和文件数量都会急剧增加,会逐渐引发以下问题:

  1. 全局污染问题
  2. 依赖混乱问题
  3. 数据安全问题

有哪些模块化规范?

随着时间的推移,针对 JavaScript 的不同运行环境,相继出现了多种模块化规范,按时间排序,分别为:

  1. CommonJS 服务端应用广泛
  2. AMD
  3. CMD
  4. ES6 模块化 浏览器端应用广泛

导入与导出

模块化的核心思想是:模块之间是隔离的,通过导入和导出进行数据和功能的共享。

  • 导出(暴露):模块公开其内部的一部分(如变量、函数等),使这些内容可以被其他模块使用
  • 导入(引入):模块引入和使用其他模块导出的内容,以重用代码和功能

CommonJS 规范

导出数据

在 CommonJS 标准中,导出数据有两种方式:

  • 第一种方式:module.exports = value
  • 第二种方式:exports.name = value
// a.js
const name = '张三'

function getTel() {return '123456789'}

module.exports = {name, getTel}

// b.js
const name = '李四'

function getTel() {return '666666666'}

// 通过给 exports 对象添加属性的方式,来导出数据
exports.name = name
exports.getTel = getTel

// index.js
// 引入 a 模块暴露的所有内容
const a = require('./a')

// 引入 b 模块暴露的所有内容
const b = require('./b')

console.log(a, a.getTel())
console.log(b, b.getTel())

注意点:

  • 每个模块内部的 this、exports、modules.exports 在初始时,都指向同一个空对象,该空对象就是当前模块导出的数据
  • 无论如何修改导出对象,最终导出的都是 module.exports 的值
  • exports 是对 module.exports 的初始引用,仅为了方便给导出象添加属性,所以不能使用 exports = value 的形式导出数据,但是可以使用 module.exports = value 导出数据

导入数据

在 CJS 模块化标准中,使用内置的 require 函数进行导入数据。

// index.js
// 1 直接引入模块
const a = require('./a')
console.log(a, a.getTel())

// 2 引入同时解构出要用的数据
const {name, getTel} = require('./a')
console.log(name, getTel())

// 3 引入同时解构 + 重命名
const {name: stuName, getTel: stuTel} = require('./a')
console.log(stuName, stuTel())

扩展理解

一个 JS 模块在执行时,是被包裹在一个内置函数中执行的,所以每个模块都有自己的作用域,可通过如下方式来验证这一说法:

// index.js
console.log(arguments.callee.toString())

内置函数大致形式如下:

function (exports, require, module, __filename, __dirname) {
  // index.js
  console.log(arguments.callee.toString())
}

浏览器端运行

Node.js 默认支持 CommonJS 规范,但浏览器端不支持,所以需要经过编译,步骤如下:

  • 第一步:全局安装 browserify:pnpm i browserify -g
  • 第二步:编译:browserify index.js -o build.js,index.js 是源文件,build.js 是输出目标文件
  • 第三步:在 index.html 页面中引入使用:<script type="text/javascript" src="./build.js"></script>

ES6 模块化规范

ES6 模块化规范是一个官方标准的规范,它是在语言标准的层面上实现了模块化功能,是目前最流行的模块化规范,且浏览器与服务端均支持该规范。

运行 ES6 模块

浏览器端可以直接运行,如在 index.html 页面中引入使用:<script type="module" src="./index.js"></script>

在 Node.js 中运行 ES6 模块代码有两种方式:

  • 方式一:将 js 文件后缀从.js 改为.mjs,Node 会自动识别 ES6 模块
  • 方式二:在 package.json 文件中设置 type 属性值为 module

导出数据

ES6 模块化提供 3 种导出方式:分别导出、统一导出、默认导出。这 3 种导出方式,可以同时使用。

使用原则:导出的常量,务必用 const 定义。

分别导出:

// a.js 分别导出
export const name = '张三'

export function getTel() {return '123456789'}

统一导出:

// b.js 统一导出
const name = '李四'

function getTel() {return '666666666'}

export {name, getTel}

默认导出:

// c.js 默认导出
const name = '王五'
export const age = 25

function getTel() {return '999999999'}

export default {name, getTel}

导入数据

对于 ES6 模块化来说,使用何种导入方式,要根据导出方式决定。

「导入全部」(通用),可将模块中的所有导出内容整合到一个对象中。

// index.js
import * as a from './a.js'

console.log(a, a.getTel())

「命名导入」(对应导出方式:分别导出、统一导出)

// index.js 命名导入
import {name, getTel} from './a.js'
import {name as stuName, getTel as stuTel} from './a.js'

console.log(name, getTel())
console.log(stuName, stuTel())

「默认导入」(对应导出方式:默认导出)

// index.js 默认导入
import c from './c.js' // 默认导出的名字可以修改,如把 c 改为 abc 也行

console.log(c.name, c.getTel())

「命名导入 与 默认导入 可以混用」,且默认导入的内容必须放在前方。

// index.js 默认导入
import c, {age} from './c.js'

console.log(c.name, c.getTel(), age)

「动态导入」(通用),允许在运行时按需加载模块,返回值是一个 Promise。

// index.js
const a = await import('./a.js')
console.log(a)

import 可以不接收任何数据,如只让 a.js 参与运行:import './a.js'

正文完
 0
阿伯手记
版权声明:本站原创文章,由 阿伯手记 于2024-07-31发表,共计2962字。
转载说明:本站原创内容,除特殊说明外,均基于 CC BY-NC-SA 4.0 协议发布,转载须注明出处与链接。
评论(没有评论)
验证码

阿伯手记

阿伯手记
阿伯手记
喜欢编程,头发渐稀;成长路上,宝藏满地
文章数
766
评论数
204
阅读量
382189
今日一言
-「
热门文章
职场救急!AI请假话术生成器:1秒定制高通过率理由

职场救急!AI请假话术生成器:1秒定制高通过率理由

超级借口 不好开口?借口交给我!智能生成工作请假、上学请假、饭局爽约、约会拒绝、邀约推辞、万能借口等各种借口理...
夸克网盘快传助手提高非VIP下载速度

夸克网盘快传助手提高非VIP下载速度

夸克网盘限速这个大家都知道,不开会员差不多限速在几百 K。那有没有办法在合法合规途径加速下载夸克网盘呢?这里推...
国内已部署DeepSeek模型第三方列表 免费满血版联网搜索

国内已部署DeepSeek模型第三方列表 免费满血版联网搜索

本文收集了目前国内已部署 DeepSeek 模型的第三方列表,个个都是免费不限次数的满血版 DeepSeek,...
TVAPP:开源电视盒子资源库,一键打造家庭影院

TVAPP:开源电视盒子资源库,一键打造家庭影院

导语 TVAPP 是一个专为 Android TV 电视盒子用户打造的开源影音资源库,集成了影视、直播、游戏等...
巴别英语:用美剧和TED演讲轻松提升英语听力与口语

巴别英语:用美剧和TED演讲轻松提升英语听力与口语

还在为枯燥的英语学习而烦恼吗?巴别英语通过创新的美剧学习模式,让英语学习变得生动有趣。平台提供海量美剧和 TE...
2025年12月 每日精选

2025年12月 每日精选

关于每日精选栏目 发现一些不错的资源,点击 这里 快速投稿。 12 月 26 日 .ax 顶级域 目前全球唯一...
Chinese Name Generator 在线中文姓名生成器

Chinese Name Generator 在线中文姓名生成器

Chinese Name Generator 是一款在线中文姓名生成器,可在几秒内生成符合个人需求的中文名字。...
最新评论
15220202929 15220202929 怎么用
八对 八对 麻烦大佬更新下【堆新】的友链站名:八对星星描述:极目星视穹苍无界•足履行者大地有疆链接:https://8dui.com图标:https://cf.8dui.com/logo.webp横标:https://cf.8dui.com/logo-w.webp订阅:https://8dui.com/rss.xml
三毛笔记 三毛笔记 已添加
DUINEW DUINEW 已添加贵站,期待贵站友链~博客名称:堆新博客地址:https://duinew.com/博客描述:堆新堆新,引力向新!——堆新(DUINEW)博客头像:https://d.duinew.com/logo.webp横版头像:https://d.duinew.com/logo-w.webp博客订阅:https://duinew.com/rss.xml
hedp hedp 没看懂
bingo bingo 直接生成就可以啦,也可以添加一些选项
满心 满心 申请更新下友联信息,原名:满心记,现名:周天记原域名:qq.mba,现域名:zhoutian.com描述:我在人间混日子
开业吉日 开业吉日 没看明白这个怎么用
开业吉日 开业吉日 beddystories 这个网站太赞了,收藏
热评文章
夸克网盘快传助手提高非VIP下载速度

夸克网盘快传助手提高非VIP下载速度

夸克网盘限速这个大家都知道,不开会员差不多限速在几百 K。那有没有办法在合法合规途径加速下载夸克网盘呢?这里推...
国内已部署DeepSeek模型第三方列表 免费满血版联网搜索

国内已部署DeepSeek模型第三方列表 免费满血版联网搜索

本文收集了目前国内已部署 DeepSeek 模型的第三方列表,个个都是免费不限次数的满血版 DeepSeek,...
清华大学官方免费DeepSeek教程

清华大学官方免费DeepSeek教程

AI 领域近期最引人注目的焦点当属 DeepSeek,这款由中国创新企业深度求索研发的人工智能工具,正以开放源...
Short-Link 免费开源短网址程序,基于Fastify、Vercel和Supabase构建

Short-Link 免费开源短网址程序,基于Fastify、Vercel和Supabase构建

Short-Link 是一款基于 Fastify、Vercel 和 Supabase 构建的 URL 缩短服务...
Chinese Name Generator 在线中文姓名生成器

Chinese Name Generator 在线中文姓名生成器

Chinese Name Generator 是一款在线中文姓名生成器,可在几秒内生成符合个人需求的中文名字。...
BeddyStories 完全免费儿童睡前故事库,让孩子随时随地入睡更轻松

BeddyStories 完全免费儿童睡前故事库,让孩子随时随地入睡更轻松

BeddyStories 是一个致力于为儿童提供优质睡前故事的在线平台,用户可以在这里找到来自世界各地的经典故...
WebRTC Screen Mirror:基于浏览器免费开源投屏神器,可实现低延迟、跨平台屏幕共享

WebRTC Screen Mirror:基于浏览器免费开源投屏神器,可实现低延迟、跨平台屏幕共享

WebRTC Screen Mirror 是一款基于 WebRTC 技术的在线屏幕共享工具,它利用浏览器内置的...