模块化概述:
(1)什么是模块化?
- 将程序文件依据一定规则拆分成多个文件,这种编码方式就是 模块化 的编码方式。
- 拆分出来每个文件就是一个模块 ,模块中的数据都是私有的 ,模块之间互相隔离。
- 同时也能通过一些手段,可以把模块内的指定数据**"交出去"**,供其他模块使用。
(2)为什么需要模块化?
随着应用的复杂度越来越高,其代码量 和文件数量都会急剧增加,会逐渐引发以下问题:
- 全局污染问题
- 依赖混乱问题
- 数据安全问题

同名函数后引入会覆盖掉前一个函数的内容
(3)有哪些模块化?
2009 年,随着 Node.js 的出现,JavaScript 在服务器端的应用逐渐增多,为了让Node.js 的代码更好维护,就必须要制定一种 Node.js 环境下的模块化规范,来自 Mozila 的工程师Kevin Dangoor 提出了 CommonJS 规范(CommonJs 初期的名字叫 ServerJs),随后 Node.js 社区采纳了这一规范。
随着时间的推移,针对 JavaScript 的不同运行环境,相继出现了多种模块化规范,按时间排序,分别为:
- CommonJS------服务端应用广泛
- AMD
- CMD
- ES6 模块化------浏览器端应用广泛
(4)导入与导出思想
模块化的核心思想就是: 模块之间是隔离 的,通过导入 和导出进行数据和功能的共享
- **导出(暴露):**模块公开其内部的一部分(如变量、函数等),使这些内容可以被其他模块使用。
- **导入(引入):**模块引用和使用其他模块导出的内容,以重用代码和功能

CommonJS 规范
(1)导出数据:
在 CommonJS 标准中,导出数据有两种方式:
- module.exports =value
- exports.name =value
注意:
1.每个模块内部的: this、exports、modules.exports 在初始时,都指向同一个空对象,该
空对象就是当前模块导出的数据,如下图:
2.无论如何修改导出对象,最终导出的都是 module.exports的值
- exports 是对 module.exports 的初始引用,仅为了方便给导出象添加属性,所以不能使用
exports = value 的形式导出数据,但是可以使用 module.exports=xxxx 导出数据。

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

解构再重命名可以解决导入重名的问题
(3)扩展:
一个JS模块在执行时,是被包裹在一个内置函数中执行的,所以每个模块都有自己的作用域,我们可以通过如下方式验证这一说法:
javascript
console.log(arguments)
console.log(arguments.callee.toString())
内置函数的大致形式如下:

ES6 模块化
ES6 模块化规范是一个官方标准的规范,它是在语言标准的层面上实现了模块化功能,是目前最流行的模块化规范,且浏览器与服务端均支持该规范。
(1)导出数据:
ES6 模块化提供3种导出方式: ①分别导出、②统一导出、③默认导出
①分别导出:

②默认导出:

③默认导出:

备注:上述多种导出方式,可以同时使用

(2)导入数据:
对于 ES6 模块化来说,使用何种导入方式,要根据导出方式决定。
①「命名导入」(对应导出方式:分别导出、统一导出)

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

「【命名导入】 与 【默认导入】可以混合使用」
③「动态导入」(通用)

import 可以不接收任何数据
数据引用问题
(1)如下代码的输出结果是什么?

结果1 1 (increment调用加的是increment函数里面的sum,但是一开始调用的是外层的sum,两个不是一个sum)
(2)使用 CommonJS 规范,编写如下代码,输出结果是什么?

同样是1 1(解构赋值)
(3)使用ES6 模块化规范编写如下代码,输出结果是什么?

let sum 的话打印出来是 1 3
最好声明为常量,因为import导入时一般为常量(只读),data.js的数据假设声明为变量,会指向同一个内存空间,这样子就能够修改sum的数据了。因此最好是将data.js的数据声明为常量。
AMD 模块化规范(了解)
①准备文件结构:

文件说明:
1.js 文件夹中存放业务逻辑代码, main.js 用于汇总各模块。
2.libs 中存放的是第三方库,例如必须要用的 require.js。
②在index.html中配置main.js 与 require.js

③在 main.js 中编写模块配置对象,注册所有块。

AMD 规范使用 define 函数来定义模块和导出数据
(1)导出数据:

(2)导入数据:

CMD 模块化规范(了解)
写法类似 CJS 和 AMD 进行结合
(1)导出数据:
CMD 中同样使用 define 函数定义模块并导出数据

(2)导入数据:
CMD 规范中使用收到的 require参数进行模块导入
