JavaScript模块化
前端模块化
模块化演进过程
全局函数
function m1(){
//...
}
function m2(){
//...
}
缺点:污染全局命名空间, 容易引起命名冲突或数据不安全,而且模块成员之间看不出直接关系
namespace
let myModule = {
data: 'www.baidu.com',
foo() {
console.log(`foo() ${
this.data}`)
},
bar() {
console.log(`bar() ${
this.data}`)
}
}
myModule.data = 'other data' //能直接修改模块内部的数据
myModule.foo() // foo() other data
Object.freeze()
Object.freeze() 静态方法可以使一个对象被冻结。冻结对象可以防止扩展,并使现有的属性不可写入和不可配置。被冻结的对象不能再被更改;不能添加新的属性,不能移除现有的属性,不能更改它们的可枚举性、可配置性、可写性或值,对象的原型也不能被重新指定。freeze() 返回与传入的对象相同的对象。
const obj = {
prop: 42,
};
Object.freeze(obj);
obj.prop = 33;
console.log(obj.prop);
IIFE模式
立即执行函数(匿名函数自调用(闭包))
(function (){
var a=1
console.log(a)
})()
匿名函数自调用(闭包)
- 作用:数据是私有的, 外部只能通过暴露的方法操作
- 编码:将数据和行为封装到一个函数内部, 通过给window添加属性来向外暴露接口
- 问题:如果当前这个模块依赖另一个模块怎么办?
// index.html文件
<script type="text/javascript" src="module.js"></script>
<script type="text/javascript">
myModule.foo()
myModule.bar()
console.log(myModule.data) //undefined 不能访问模块内部数据
myModule.data = 'xxxx' //不是修改的模块内部的data
myModule.foo() //没有改变
</script>
// module.js文件
(function(window) {
let data = 'www.chenghuai.com'
//操作数据的函数
function foo() {
//用于暴露有函数
console.log(`foo() ${
data}`)
}
function bar() {
//用于暴露有函数
console.log(`bar() ${
data}`)
otherFun() //内部调用
}
function otherFun() {
//内部私有的函数
console.log('otherFun()')
}
//暴露行为
window.myModule = {
foo, bar } //ES6写法
})(window)
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文件