1、高级单例模式
高级单例模式:创建一个命名空间(模块名)接收闭包中返回的相关信息,实现把闭包中的某些信息暴露出来,供其它的闭包调用;
(1)、代码示例
/* let module1 = (function () {
let name = '哈哈';
function query() {
}
function fn() {
console.log('FN');
}
return {
query: query
}
})();
let module2 = (function () {
function fn() {
console.log('FN2');
}
module1.query();
return {};
})(); */
(2)、代码示例
<script>
let utils = (function () {
return {
// ...
}
})();
let wetherModule = (function () {
// ...自己的方法
return {
init() {
// ...按照业务顺序逐一加载对应的方法
}
}
})();
wetherModule.init();
// ...
</script>
2、AMD
moduleA.js
/*
* AMD思想中,模块的定义基于 define 完成
* define([name]?,[dependence]?,[factory])
*/
define(function () {
// 任意数求和
function sum(...args) {
let len = args.length;
if (len === 0) return 0;
if (len === 1) return args[0];
return args.reduce((total, item) => {
return total + item;
});
}
// 把指定的方法暴露到外面
return {
sum
};
});
moduleB.js
/* AMD思想需要在定义新的模块之前,把依赖的模块事先导入可以 */
define([
'moduleA'
], function (moduleA) {
//=>moduleA存储的就是 'js/lib/moduleA' 这个模块导出的内容
function average(...args) {
let len = args.length;
if (len === 0) return 0;
if (len === 1) return args[0];
return (moduleA.sum(...args) / args.length).toFixed(2);
}
return {
average
}
});
main.js
require.config({
baseUrl: 'js/lib'
});
/*
* AMD中导入某一个模块基于 require
* require([dependence],[callback])
*/
require([
'moduleB',
// 'moduleA'
], function (moduleB) {
let result = moduleB.average(10, 20, 30, 40, 50);
console.log(`平均数是:${result}`);
// result = moduleA.sum(10, 20, 30, 40, 50);
// console.log(`和是:${result}`);
自己实现AMD规范
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0">
<!-- IMPORT CSS -->
</head>
<body>
<!-- IMPORT JS -->
<script>
let factories = {};
/* 课后思考:define也需要设置依赖? */
function define(moduleName, factory) {
factories[moduleName] = factory;
}
function require(dependence, callback) {
dependence = dependence.map(item => {
return factories[item]();
});
callback(...dependence);
}
define('moduleA', function () {
return {
fn() {
console.log('moduleA');
}
};
});
define('moduleB', function () {
return {
fn() {
console.log('moduleB');
}
};
});
require(['moduleA', 'moduleB'], function callback(moduleA, moduleB) {
moduleA.fn();
moduleB.fn();
});
</script>
</body>
</html>
3、 CommonJS
moduleA.js
/*
* require 导入模块
* module.exports 导出模块中的方法
*/
function sum(...args) {
let len = args.length;
if (len === 0) return 0;
if (len === 1) return args[0];
return args.reduce((total, item) => {
return total + item;
});
}
module.exports = {
sum
};
moduleB.js
/*
* 每一次REQUIRE都会先把moduleA执行一遍,把它基于
module.exports导出的对象克隆一份给moduleA变量
*/
let moduleA = require('./moduleA');
function average(...args) {
let len = args.length;
if (len === 0) return 0;
if (len === 1) return args[0];
return (moduleA.sum(...args) / args.length).toFixed(2);
}
module.exports = {
average
};
main.js
// ....
let moduleB = require('./moduleB');
console.log(moduleB.average(10, 20, 30, 40, 50));
// ...
let moduleA = require('./moduleA');
console.log(moduleA.sum(10, 20, 30, 40, 50));
/*
* CMD相对于AMD来讲,不需要前置依赖,什么时候用到,什么时候导入即可,而且Node环境下的CommonJS规范中,会把每一次导入的模块做缓存(后期再重新导入直接把上一次导入拷贝的结果复制一份过来即可)
*/
/*
* ES6Module和CommonJS具备相同的机制:避免重复导入
* import 导入
* export / export default 导出
*
* 特点:我们会在当前模块最开始的位置,基于import把所有依赖模块导入进来
*
* CommonJS是运行时加载 ,ES6Module(在项目中一般配合webpack来使用)是在编译时处理
*/
4、UMD规范
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0">
<!-- IMPORT CSS -->
</head>
<body>
<!-- IMPORT JS -->
<script>
(function (global, factory) {
if (typeof module === "object" && typeof module.exports === "object") {
//... NODE环境下基于CommonJS规范实现的
} else {
//... 浏览器端运行
}
})(typeof window !== "undefined" ? window : this, function (window, noGlobal) {
// ...
});
</script>
</body>
</html>