面试必会---模块化
概念
什么是模块, 一个模块是一块具有独立功能的代码, 可以是一个函数, 一个对象,甚至是一个字符串或数字,通常存储为一个单独的j s文件。
为什么需要模块化?
过去,j s很难编写大型应用, 因为有以下两个问题:
- 全局变量污染
- 难以管理的依赖关系
这两个问题导致j s无法进行精细的模块划分, 因为精细的模块划分会导致更多的全局污染以及更加复杂的依赖关系。
于是先后出现了两大模块化标准, 用于解决以上两个问题:
- commonJs => amd => cmd (被历史的车轮碾碎)
- ES6 Module
commonJs
目前只有node环境才支持commonJs模块化标准, 所以要使用commonJs, 必须安装node
Nodejs遵循ecmascript标准, 但是由于脱离了浏览器环境, 因此:
-
你可以在nodej s里使用ecmascript标准的任何语法或API,例如:循环,判断,数组,对象等
-
你不能在nodej s里使用浏览器的web api ,例如: document对象, window对象, dom对象, Location,
History 等等
Node 的全局变量叫做 global
commonJs标准和使用
node中的所有代码都是在commonJs规范中运行的
具体规范如下:
- 一个Js文件就是一个模块
- 如果一个模块需要暴露一些数据或者功能,需要用module.exports = xxx 导出
- 如果一个模块需要使用另一个模块导出的内容,需要使用require("模块路径")
- 路径必须以./或者../开头
- 如果模块文件后缀名为.js, 可以省略后缀名
- require函数返回的是模块导出的内容
- 模块中的所有全局代码产生的变量,函数,均不会对全局造成任何污染,仅在模块内使用
- 模块具有缓存, 第一次导入模块时会缓存模块的导出, 之后再导入同一个模块,直接使用之前缓存的结果
原理
为什么使用module.exports可以实现导出?
node实际上是将模块文件中的代码放置到一个函数环境中执行, 该函数类似下面的样子
function(module) {
module.exports = {};
var exports = module.exports;
// 模块中的代码。
return module.exports;
}
ES6 Module
由于种种原因, commonjs 标准难以在浏览器中实现, 因此浏览器端一直没有合适的模块化标准,直到ES6标准出现, ES6规范了浏览器的模块化标准,一经发布,各大浏览器厂商纷纷在自己的浏览器中实现了该规范。
模块引入
浏览器使用以下方式引入一个ES6模块化文件
<script src="./xxx.js" type="module"></script>
模块导出
-
模块导出分为两种, 基本导出和默认导出
-
基本导出
-
export var a = 1 // 基本导出a=1 var c = 3; export {c} // 基本导出c=3. var c = 3; export {c as temp} // 基本导出temp=3. export {c as default} // 默认导出default = 3。
-
-
默认导出
-
export default 3 // 默认导出default = 3
-
-
我们平时 直接 export default 一把梭。
模块导入
import {a, b} from "模块路径"
import {a as temp1 , b as temp2} from "模块路径"
import {defalut as a} from "模块路径"
import c from "模块路径" //相当于import {defalut as c} from "模块路径"
import * as obj from "模块路径"
模块导入时注意
- ES6 module 采用依赖预加载模式, 所有模块导入均会提升到代码顶部
- 不能将导入代码放置到判断, 循环中
- 导入的内容放置到常量中, 不可更改
- ES6 module使用了缓存, 保证每个模块仅加载一次