定义:模块是一个提供接口却隐藏状态与实现的函数或对象
我们可以用函数和闭包来构造模块
- 例子一:
假定要给String增加一个deentityify方法。它的任务是寻找字符串中的html字符实体并把它们替换成对应的字符。
分析:- 需要在一个对象中保存字符实体的名字和它们对应的字符。
- 这个对象放置的位置考虑:
- 把它放在一个全局变量中,但全局变量是魔鬼
- 把它定义在函数的内部,但是会带来运行时的损耗。因为每次执行该函数的时候该字面量都会被求值一遍。
- 理想的方式是把它放在一个闭包,而且也许还能提供一个增加更多字符实体的扩展方法
String.method('deentityify', function(){ // 字符实体表。它映射字符实体的名字到对应的字符 var entity = { quot: '"' , lt: '<', gt: '>' }; // 返回deentityify方法 return function(){ // 这才是deentityify方法。它调用字符串的replace方法 return this.replace(/&([^&;]+);/g, function(a, b){ var r = entity[b]; return typeof r === 'string' ? r : a; } ); }; }()); // 调用 var str = "1 + 2 < 4"; parseStr = str.deentityify(); console.log(parseStr);
- 例子二:
构造一个用来产生序列号的对象
模块模式通常结合单例模式使用,javascript的字面量创建对象就是单例模式。var serial_maker = function(){ // 返回一个用来产生唯一字符串的对象 // 唯一字符串由两部分组成:前缀+序列号 // 该对象包含一个设置前缀的方法,一个设置序列号的方法 // 和一个产生唯一字符串的gensym方法 var prefix = ''; var seq = 0; return { set_prefix: function(p){ prefix = String(p); }, set_seq: function(s){ seq = s; }, gensym: function(){ var result = prefix + seq; seq += 1; return result; } } }
它通常作为工具为其它部分提供功能支持