前言
- 一个 HTML 文件中引入了 a.js 和 b.js ,如何解决两个文件中同名变量的问题?
- 一个 HTML 文件中引入了 a.js 和 b.js , 如何解决污染全局变量的问题?
- 一个 HTML 文件中引入了 a.js 和 b.js ,且 b.js 依赖于 a.js 中的一个变量,手动维护引入文件的先后顺序?
ES6之前的解决方案
使用 IIFE
(function() { // 使用IIFE隔离作用域
let a = 1
let b = 2
})()
使用AMD (asynchronous Module Definition 异步模块定义),代表库 require.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="js/require.js" data-main="js/main.js"></script>
</body>
</html>
- main.js 中需要使用 require 方法获取依赖的文件名(不能文件名后缀),将将每个文件所暴露的对象按顺序注入到回函函数参数中
// 获取向外暴露的文件 然后将暴露的对象按顺序注入到回调函数中
require(['rectangle', 'circle'], function (rectangle, circle) {
console.log('矩形面积', rectangle.area(10, 5))
console.log('圆形面积', circle.area(10));
})
- rectangle.js 中使用 define 方法定义向外暴露的对象
/**
* 计算矩形面积
*/
define(function() {
function area(length, width) {
return length * width
}
return { // 向外暴露对象
area
}
})
- circle.js 中也使用 define 方法向外暴露对象,给 require 方法使用
/**
* 计算圆的面积
*/
define(function() {
function area(r) {
return Math.PI * r * r
}
return { // 向外暴露对象
area
}
})
- 使用 AMD 可以解决文件之间变量同名问题,文件之间相互依赖问题、污染全局变量问题
- AMD暴露规范指的是什么? define 函数参数中传递一个回调函数,该回调函数返回一个对象
使用CMD (common module module 通用模块定义),代表 seajs 、 node.js
- 引入 sea.js 并指定入口文件 main.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<script src="js/sea.js"></script>
<script>
seajs.use('./js/main.js')
</script>
</body>
</html>
- 在 入口文件 mina.js 中通过 require 引入 circle.js 和 rectangle.js 并使用其中的 area 方法
define(function (require, exports, module) {
const c = require('./circle.js')
const r = require('./rectangle.js')
console.log(c.area(10)); // 314
console.log(r.area(10, 20)); // 200
})
- 定义 circle.js 方法
define(function (require, exports, module) {
function area(r) {
return 3.14 * r * r
}
exports.area = area
})
- 定义 rectangle.js 方法
define(function (require, exports, module) {
function area (length, width) {
return length * width
}
exports.area = area
})
- node.js 中不用写 define 函数是因为被封装了
AMD 和 CMD 区别
- AMD 中的 require 方法加载模块异步的,require 函数中的依赖项全部加载完毕后,才会执行回调函数
- CMD 中的 require 方法加载模块是同步的
ES6的 module 模块化
- ES6从语言层面上支持了模块化功能( 指定 script 标签的 type 属性为 module )
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="./js/a.js" type="module"></script>
</body>
</html>
- 使用 import 导入模块
import { b } from './b.js'
console.log(b)
- 使用 export 导出模块