JavaScript原始功能
- 在早期的网页开发时期, js的代码很少, 都是直接将js代码写到html代码中的script标签中就可以了
- 随着ajax异步请求的出现, 慢慢形成了前后端分离
- 用户需求越来越多, 代码与日俱增
- 为了应对代码量的剧增, 我们将代码写到多个js文件中, 进行维护
- 但是这样容易引起变量泄露等等的严重问题
- 可以使用匿名函数闭包来解决变量泄露的问题
如何使用闭包防止变量泄露
- 原理
- 利用函数自身的块级作用域特性, 函数内部的变量, 外部无法访问
- 将想要暴露出去的变量和函数, 打包在一个对象中
- 通过return 的方法 将打包好的对象暴露出去
- 在函数的外面用一个变量接收这一个对象
- 在其他的模块中引用
- 具体代码
let ModuleA = (function () {
function sum() {};
let flag = true;
let obj = {};
obj.sum = sum;
obj.flag = flag;
return obj;
})()
ModuleA.sum()
ModuleA.flag;
- 以上的代码就是模块最基础的封装了, 事实上模块的封装还有很多高级的写法
- 很幸运的是, 前端模块化的开发已经又很多的既有规范, 已经对应的实现方案
常见的模块化规范
- CommonJS AMD CMD 还有ES6的Modules
- 开发常用的是NodeJS中的CommonJS 和 ES6中的Modules
CommonJS模块化规范
- 模块化规范都是围绕两个核心来进行的, 导出和导入
- CommonJS的导出和导入基本雏形
module.exports = {
flag : true,
test() {}
}
let {flag,test} = require("module");
ES6的模块化
- 在引入js文件的script标签中, 定义type属性, 值为module, 来模块化js文件
- 在各个模块中通过export导出信息, import导入信息
- 注意事项
- 导入默认的信息时, 不需要加大括号, 而且名字可以自定义
- 通过通配符 * 导入所有被导出的信息 import * as 自定义名字 from “模块地址”
- 这个自定义名字就是 * 的别名, 方便后续的使用
- 实际上就是将 ModuleA 中导出的所有信息 * , 集合到 自定义名字 这个对象中
<body>
<script src="./ModuleA.js" type="module"></script>
<script src="./ModuleB.js" type="module"></script>
</body>
let flag = true;
let name = "xiaoLam";
function sum(num1,num2) {
return num1 + num2;
}
export {flag, name, sum};
export let age = 18;
export function run() {
console.log("我在跑");
}
export class Person {
walk() {
console.log("我在走");
}
}
const me = "xiaoLam";
export default me;
import {flag, name,sum} from "./ModuleA.js";
console.log(flag);
console.log(name);
console.log(sum(10,20));
import {age, run} from "./ModuleA.js";
console.log(age);
run();
import {Person} from "./ModuleA.js";
let xiaoLam = new Person();
xiaoLam.walk();
import you from "./ModuleA.js";
console.log(you);
import * as objA from "./ModuleA.js";
console.log(objA);
console.log(objA.name);