第一阶段:无模块化
| |
|
简单的将所有的js文件统统放在一起。但是这些文件的顺序还不能出错,比如jquery需要先引入,才能引入jquery插件,才能在其他的文件中使用jquery。
|
|
优点:
|
|
缺点:
|
函数封装
| |
|
优点
|
|
缺点
|
命名空间方式(对象封装)
| |
|
每个模块只暴露一个全局对象
命名空间的方式只是解决了命名冲突的问题
|
|
优点
|
|
缺点
|
IIFE(立即执行函数)
| |
|
使用立即执行函数表达式(IIFE,Immediately-Invoked Function Expression)为模块提供私有空间
|
|
|
|
优点:
|
|
缺点:
|
// 函数封装
└─ stage-1
├── module-a.js
├── module-b.js
└── index.html
// module-a.js
function foo () {
console.log('moduleA#foo')
}
// module-b.js
var data = ‘something'
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Stage 1</title>
</head>
<body>
<script src="module-a.js"></script>
<script src="module-b.js"></script>
<script>
// 直接使用全局成员
foo() // 可能存在命名冲突
console.log(data)
data = 'other' // 数据可能会被修改
</script>
</body>
</html>
// 命名空间方式(对象封装)
// module-a.js
window.moduleA = {
method1: function () {
console.log('moduleA#method1')
}
}
// module-b.js
window.moduleB = {
data: 'something',
method1: function () {
console.log('moduleB#method1')
}
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Stage 2</title>
</head>
<body>
<script src="module-a.js"></script>
<script src="module-b.js"></script>
<script>
moduleA.method1();
moduleB.method1(); // 模块成员依然可以被修改
moduleA.data = 'foo'
</script>
</body>
</html>
// IIFE
// module-a.js
;(function () {
var name = 'module-a'
function method1() {
console.log(name + '#method1')
}
window.moduleA = {
method1: method1
}
})()
// IIFE 引入依赖
// module.js文件
(function (window, $) {
let data = 'www.baidu.com';
//操作数据的函数
function foo() {
//用于暴露有函数
console.log(`foo() ${data}`);
$('body').css('background', 'red');
}
function bar() {
//用于暴露有函数
console.log(`bar() ${data}`);
otherFun(); //内部调用
}
function otherFun() {
//内部私有的函数
console.log('otherFun()');
}
//暴露行为
window.myModule = { foo, bar };
})(window, jQuery);
// index.html文件
<!-- 引入的js必须有一定顺序 -->
<script type="text/javascript" src="jquery-1.10.1.js"></script>
<script type="text/javascript" src="module.js"></script>
<script type="text/javascript">
myModule.foo();
</script>
// 揭示模块模式 Revealing module pattern
var myGradesCalculate = (function () {
// 在函数的作用域中下面的变量是私有的
var myGrades = [93, 95, 88, 0, 55, 91];
var average = function () {
var total = myGrades.reduce(function (accumulator, item) {
return accumulator + item;
}, 0);
return 'Your average grade is ' + total / myGrades.length + '.';
};
var failing = function () {
var failingGrades = myGrades.filter(function (item) {
return item < 70;
});
return 'You failed ' + failingGrades.length + ' times.';
};
// 将公有指针指向私有方法
return {
average: average,
failing: failing,
};
})();
myGradesCalculate.failing(); // 'You failed 2 times.'
myGradesCalculate.average(); // 'Your average grade is 70.33333333333333.'