模块化
模块化
模块化概述
将程序文件依据一定规则拆分成多个文件,这种编码方式就是模块化的编码方式。拆分出来的每个文件就是一个模块,模块中的数据都是私有的,模块之间互相隔离。同时也能通过一定手段,把模块中的指定数据交出去,供其他模块使用。
模块化好处
随着应用的复杂度越来越高,其代码量和文件数量都会急剧增加,会逐渐引发以下问题。
- 全局污染问题(变量名太多)
- 依赖混乱问题
- 数据安全问题
模块化规范
历史背景:2009年,随着Node.js的出现,JavaScript在服务器端的应用逐渐增多,为了让Node.js的代码更好维护,就必须指定一种Node.js环境下的模块化规范,来自Mozila(知名应用火狐浏览器)的工程师kevin Dangoor提出了CommonJS规范(初期名字叫ServerJS),随后Node.js社区采纳了这一规范。
随着时间的推移,针对JavaScript的不同运行环境,相继出现了多种模块化规范,按时间排序,分别为:
CommonJS -- 服务端应用广泛
AMD
CMD
ES6 模块化 -- 浏览器端应用广泛
导入与导出
模块化的核心思想:模块之间是隔离的,通过导入和导出进行数据和功能的共享。
导出:模块公开其内部的一部分(变量、函数等),是这些内容可以被其他模块使用。
导入:模块引用和使用其他模块导出的内容,以重用代码和功能。
CommonJS规范
const name = 'tensoflow'
const address = '拉尼亚凯亚超星系团'
// 导出方式一:exports
// exports本质就是一个对象,你想导出什么数据就往这个对象中加东西
// 导入的时候接收的就是这个对象
exports.name = name
exports.address = address
// 导出方式二
module.exports = {
name,
address
}
// 导入
const school = require('./school.js')
console.log(school) // { name: 'tensoflow', address: '拉尼亚凯亚超星系团' }
注意
每个模块内部:this、exports、module.exports在初始时,都指向同一个空对象,该空对象就是当前模块导出的数据。无论如何修改导出对象,最终导出的都是module.exports的值。exports是对module.exports的初始引用,仅为了方便给导出对象添加属性,所以不能用exports = value的形式导出数据,但是可以使用module.exports = value的形式导出数据。
小贴士
Node.js默认是支持CommonJS规范的,但是浏览器端不支持,所以需要经过编译 。可通过npm i browserify安装browserify依赖帮助编译。编译命令browserify index.js -o build.js意思是将你写的index.js编译并生成build.js,然后在html页面中引入build.js而不是index.js。
ES6 模块化规范
ES6 模块化规范是一个官方标准的规范,它是在语言标准的层面上实现了模块化功能,是目前最流行的模块化规范,且浏览器与服务端均支持该规范。
// 分别导出:需要导出什么数据就在前面加上export
export const name = 'tensoflow'
export const address = '拉尼亚凯亚超星系团'
// 导入所有并起别名叫school
import * as school from './school.js'
console.log(school.name) // tensoflow
console.log(school.address) // 拉尼亚凯亚超星系团
// 命名导入
import { name } from './school.js'
console.log(name) // tensoflow
// 命名导入并起别名
import { name as schoolName } from './school.js'
console.log(schoolName) // tensoflow
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>TenSoFlow</title>
</head>
<body>
<div>tensoflow</div>
<!-- type要写module而不是text/javascript -->
<!-- 如果直接用浏览器打开此HTML会报错 -->
<!-- 浏览器为了安全考虑不允许本地HTML随意读取用户电脑上的JS文件防止恶意页面窃取本地数据 -->
<!-- 可以在VSCode安装Live Server插件,然后右键 index.html → Open with Live Server -->
<script type="module" src="./index.js"></script>
</body>
</html>
// 统一导出:需要导出什么数据在最后面的export{}中放入
// 注意:最后的export{}中{}并不是表示对象的意思,
// 所以也不能使用对象的语法如{ name:name }
// 而是想导出什么就直接写定义过的变量名并用逗号分隔。
const name = 'tensoflow'
const address = '拉尼亚凯亚超星系团'
export {
name,
address
}
// 导入所有并起别名叫school
import * as school from './school.js'
console.log(school.name) // tensoflow
console.log(school.address) // 拉尼亚凯亚超星系团
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>TenSoFlow</title>
</head>
<body>
<div>tensoflow</div>
<!-- type要写module而不是text/javascript -->
<!-- 如果直接用浏览器打开此HTML会报错 -->
<!-- 浏览器为了安全考虑不允许本地HTML随意读取用户电脑上的JS文件防止恶意页面窃取本地数据 -->
<!-- 可以在VSCode安装Live Server插件,然后右键 index.html → Open with Live Server -->
<script type="module" src="./index.js"></script>
</body>
</html>
// 默认导出:export default后面只能有一个值
const student = {
name: 'tensoflow',
address: '拉尼亚凯亚超星系团'
}
export default student
// 导入所有并起别名叫school
import * as school from './school.js'
// 注意:默认导出是放到default对象中的,所以要加一层default
console.log(school.default.name) // tensoflow
console.log(school.default.address) // 拉尼亚凯亚超星系团
// 简写:如果使用的是默认导出则可以用任意名称的变量接收
import school from './school.js'
console.log(school.name) // tensoflow
console.log(school.address) // 拉尼亚凯亚超星系团
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>TenSoFlow</title>
</head>
<body>
<div>tensoflow</div>
<!-- type要写module而不是text/javascript -->
<!-- 如果直接用浏览器打开此HTML会报错 -->
<!-- 浏览器为了安全考虑不允许本地HTML随意读取用户电脑上的JS文件防止恶意页面窃取本地数据 -->
<!-- 可以在VSCode安装Live Server插件,然后右键 index.html → Open with Live Server -->
<script type="module" src="./index.js"></script>
</body>
</html>
// 混合导出:三种导出方式可混合使用
export const name = 'tensoflow'
const address = '拉尼亚凯亚超星系团'
const age = 18
export { address }
export default {
age
}
// 导入所有并起别名叫school
import * as school from './school.js'
// { address: '拉尼亚凯亚超星系团', default: { age: 18 }, name: 'tensoflow' }
console.log(school)
// 如果是混合导出可以先用任意名称接收默认导出数据,后面的{}中接收分别导出和统一导出数据
import studentAge, { name, address } from './school.js'
console.log(studentAge) // { age: 18 }
console.log(name) // tensoflow
console.log(address) // 拉尼亚凯亚超星系团
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>TenSoFlow</title>
</head>
<body>
<div>tensoflow</div>
<!-- type要写module而不是text/javascript -->
<!-- 如果直接用浏览器打开此HTML会报错 -->
<!-- 浏览器为了安全考虑不允许本地HTML随意读取用户电脑上的JS文件防止恶意页面窃取本地数据 -->
<!-- 可以在VSCode安装Live Server插件,然后右键 index.html → Open with Live Server -->
<script type="module" src="./index.js"></script>
</body>
</html>
