javascript七基础学习系列二千八百一十六:凑合的模块系统

为按照模块模式提供必要的封装,ES6 之前的模块有时候会使用函数作用域和立即调用函数表达式
(IIFE,Immediately Invoked Function Expression)将模块定义封装在匿名闭包中。模块定义是立即执行
的,如下:
(function() {
// 私有Foo 模块的代码
console.log(‘bar’);
})();
// bar
如果把这个模块的返回值赋给一个变量,那么实际上就为模块创建了命名空间:
var Foo = (function() {
console.log(‘bar’);
})();
‘bar’
为了暴露公共API,模块IIFE 会返回一个对象,其属性就是模块命名空间中的公共成员:
var Foo = (function() {
return {
bar: ‘baz’,
baz: function() {
console.log(this.bar);
}
};
})();
console.log(Foo.bar); // ‘baz’
Foo.baz(); // ‘baz’
类似地,还有一种模式叫作“泄露模块模式”(revealing module pattern)。这种模式只返回一个对象,
其属性是私有数据和成员的引用:
var Foo = (function() {
var bar = ‘baz’;
var baz = function() {
console.log(bar);
};
return {
bar: bar,
baz: baz
};
})();
console.log(Foo.bar); // ‘baz’
Foo.baz(); // ‘baz’
在模块内部也可以定义模块,这样可以实现命名空间嵌套:
var Foo = (function() {
return {
bar: ‘baz’
};
})();
Foo.baz = (function() {
return {
qux: function() {
console.log(‘baz’);
}
};
})();
console.log(Foo.bar); // ‘baz’
Foo.baz.qux(); // ‘baz’
为了让模块正确使用外部的值,可以将它们作为参数传给IIFE:
var globalBar = ‘baz’;
var Foo = (function(bar) {
return {
bar: bar,
baz: function() {
console.log(bar);
}
};
})(globalBar);
console.log(Foo.bar); // ‘baz’
Foo.baz(); // ‘baz’
因为这里的模块实现其实就是在创建JavaScript 对象的实例,所以完全可以在定义之后再扩展模块:
// 原始的Foo
var Foo = (function(bar) {
var bar = ‘baz’;
return {
bar: bar
};
})();
// 扩展Foo
var Foo = (function(FooModule) {
FooModule.baz = function() {
console.log(FooModule.bar);
}
return FooModule;
})(Foo);
console.log(Foo.bar); // ‘baz’
Foo.baz(); // ‘baz’
无论模块是否存在,配置模块扩展以执行扩展也很有用:
// 扩展Foo 以增加新方法
var Foo = (function(FooModule) {
FooModule.baz = function() {
console.log(FooModule.bar);
}
return FooModule;
})(Foo || {});
// 扩展Foo 以增加新数据
var Foo = (function(FooModule) {
FooModule.bar = ‘baz’;
return FooModule;
})(Foo || {});
console.log(Foo.bar); // ‘baz’
Foo.baz(); // ‘baz’
当然,自己动手写模块系统确实非常有意思,但实际开发中并不建议这么做,因为不够可靠。前面
的例子除了使用恶意的eval 之外并没有其他更好的动态加载依赖的方法。因此必须手动管理依赖和排
序。要添加异步加载和循环依赖非常困难。最后,对这样的系统进行静态分析也是个问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值