- 未来的开发都是“模块化开发
- 把项目的代码分别写在一个个的模块下,最后把所有的模块合并在一起「webpack/vite」
- 如果每个模块下,写的代码都是全局声明的,最后在合并的时候,可能导致全局变量污染
- 解决方法:闭包
- 问题:都是私有的了,这样模块之前无法相互访问了
- 我们需要把闭包中的某些东西暴露到外面给其他模块使用
单例设计模式(Single)
- 最早的模块化开发解决方案
- 首先基于“闭包”避免了全局变量的污染
再基于“命名空间/模块名”的方式,把闭包中的某些方法暴露出来,供其他模块调用
const 命名空间=(function(){
// 本模块下需要编写的程序
....
return {
// 需要暴露给外部调用的方法
...
}
})()
命名空间.xxx() // 后面的执行都基于命名空间的成员访问方式处理
弊端:在创建的模块变多的时候,因为模块之间存在“依赖”,所以需要“手动分析”模块之间的依赖,按照顺序,依次在页面中导入对应的模块「这个工作很“恶心”」
==> AMD模块化思想「插件:require.min.js,其内部提供了“模块依赖管理”的机制
AMD
AMD模块化开发思想和模式
- 问题: AMD采用的是“前置导入”「把所有依赖的模块,在最开始就指定好」
- 不方便
- 每一个模块处理之前,需要把依赖的模块先导入执行,如果依赖的模块比较多,则性能会变慢一些
- ===> 按需导入 ( CommonJS )
![]2XDH59NKT41N2BJ(LPHQ.jpg![{S}A8]6H}{CSPO7GMZ(I`T.jpg](https://cdn.nlark.com/yuque/0/2023/jpeg/36232707/1689659748725-39728461-a7ed-4e03-8804-344ec6018cff.jpeg#averageHue=%23fbfafa&clientId=u655617f3-13a3-4&from=drop&id=u6bd15bef&originHeight=870&originWidth=1564&originalType=binary&ratio=1.100000023841858&rotation=0&showTitle=false&size=147753&status=done&style=none&taskId=ue35ee2af-005b-4879-9008-99a8abdedaf&title=)
CommonJS
只能在Node(类Node「webpack」)环境下运行,不能用于浏览器端
- 原先淘宝的一个大神,基于JS重写了一套CommonJS规范「插件:sea.js」,旨在,在浏览器端也支持按需导入(CommonJS规范)
![]D4Q}T4O9{6OO~VUCPY)K9_tmb.jpg
ES6Module
CommonJS规范只能用于 Node+Webpack 环境下
ES6Module规范(ES规范)只能用于 浏览器+Webpack 环境下
JS可以运行的环境
- 浏览器「webview」
- webpack「实现了ES规范和CommonJS规范的混淆」
- Node
- …![KZZ7`E5H_NCZQ}B~F_SD5O.jpg
模块导出:export 或者 export default
无论基于何种方式,模块导出的永远是一个“Module对象”!!
第一种方式:export
- 一个模块中可以使用多次,分别导出多项内容
- 导出的每一项内容,都是给“Module对象”设置相关的成员
第二种方式:export default
- 一个模块中只能用一次
- 它是给“Module对象”设置一个叫做default的成员,成员值是导出的内容
在ES6Module的模式下,创建一个JS文件,就相当于创建一个模块,内部编写的代码都是私有的,无需我们自己基于闭包处理
export 后面必须放一个创建变量和值的表达式(不能直接放一个值)
- export sum //错误
- export const x = 10 //正确
- export function fn() { }
- export const obj = {}
可以放一个类似于“对象”,类似于“代码块”
- 把大括号中的每一项,作为“Module对象”的成员和对应的值{但是需要这些内容在上面已经声明+定义了}
export {
sum,
name,
// x:10 //错误语法,它不是对象
// const x=10 //错误语法,它不是代码块
}
export default 后面放啥值都可以(但是需要是一个值,不能是创建值的表达式)
- export default const x = 10 //错误
- export default function(){} //正确
- export default sum //正确
- export default { //正确
sum
}
模块导入:把模块导出的“Module对象”中的每一项内容拿到 => import
import … from ‘模块地址’
- 相对地址
- 不能省略后缀名「在webpack中可以省略提前配置好的后缀」
语法一:
import 变量 from ‘./A.js’
不是把“Module对象”整体导入进来赋值给“变量”,而是只拿到了“Module对象.default”属性值「变量=Module对象.default」「换句话说,基于export default xxx导出的内容,用这种方式直接导入」
语法二:
import {x,y} from ‘./A.js’
用解构赋值的方式获取导出的内容,首先不是把“Module对象.default属性值”进行解构赋值;而是直接给“Module对象”解构赋值「换句话来讲,它是获取基于 export let xxx=xxx 这种方式导出的内容」
语法三:
import * as A from ‘./A.js’
把模块导出的“Module对象”中的所有内容都拿到,最后赋值给A「A=Module对象」