JS编程建议——69:使用模块化规避缺陷

简介: 69:使用模块化规避缺陷

建议69:使用模块化规避缺陷
使用函数和闭包可以构建模块。所谓模块,就是一个提供接口却隐藏状态与实现的函数或对象。通过使用函数构建模块,可以完全摒弃全局变量的使用,从而规避JavaScript语言缺陷。全局变量是JavaScript最为糟糕的特性之一,在一个大中型Web应用中,全局变量可能会带来不可预料的后果。
例如,要为String扩展一个deentityify方法,其设计任务是寻找字符串中的HTML字符实体并将其替换为对应的字符。在一个对象中保存字符实体的名字及与之对应的字符是有意义的。
可以把deentityify放到一个全局变量中,但全局变量存在很多潜在危害。可以把deentityify定义在该函数本身中,但会带来运行时的损耗,因为在该函数每次被执行时,这个方法都会被求值一次。理想的方式是将deentityify放入一个闭包,而且也许还能提供一个增加更多字符实体的扩展方法。
String.method('deentityify', function() {

var entity = {
    quot : '"',
    lt : '<',
    gt : '>'
};
return function() {
    return this.replace(/&([^&;]+);/g, function(a, b) {
        var r = entity[b];
        return typeof r === 'string' ? r : a;
    });
};

}());
在上面代码中,为String类型扩展了一个deentityify方法,它调用字符串的replace方法来查找以“&”开头和以“;”结束的子字符串。如果这些字符可以在字符实体表entity中找到,那么就将该字符实体替换为映射表中的值。deentityify方法用到了一个正则表达式:
return this.replace(/&(1+);/g, function(a, b) {

var r = entity[b];
return typeof r === 'string' ? r : a;

});
在最后一行使用()运算符立刻调用刚刚构造出来的函数。这个调用所创建并返回的函数才是deentityify方法。
document.writeln('<">'.deentityify()); // <">
模块利用了函数作用域和闭包来创建绑定对象与私有成员的关联。在这个示例中,只有deentityify方法才有权访问字符实体表entity这个数据对象。模块开发的一般形式是:一个定义了私有变量和函数的函数,利用闭包创建可以访问到的私有变量和函数的特权函数,最后返回这个特权函数,或者把它们保存到可访问的地方。
使用模块可以避免全局变量的滥用,从而保护信息的安全性,实现优秀的设计实践。使用这种模式也可以实现应用程序的封装,或者构建其他实例对象。
模块模式通常结合实例模式使用。JavaScript的实例就是用对象字面量表示法创建的,对象的属性值可以是数值或函数,并且属性值在该对象的生命周期中不会发生变化。模块通常作为工具为程序其他部分提供功能支持。通过这种方式能够构建比较安全的对象。
下面代码构造一个用来产生序列号的对象。serial_maker()函数将返回一个用来产生唯一字符串的对象,这个字符串由两部分组成:字符前缀+序列号。这两部分可以分别使用set_prefix和set_seq方法进行设置,然后调用实例对象的gensym方法读取这个字符串。当执行该方法时,都会自动产生唯一一个字符串。
var serial_maker = function() {

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;
    }
};

};
var seqer = serial_maker();
seqer.set_prefix('Q');
seqer.set_seq(1000);
var unique = seqer.gensym(); //"Q1000"
var unique = seqer.gensym(); //"Q1001"
seqer包含的方法都没有用到this或that,因此没有办法“损害”seger,除非调用对应的方法,否则无法改变prefix或seq的值。由于seqer对象是可变的,所以它的方法可能会被替换掉,但替换后的方法依然不能访问私有成员。seqer就是一组函数的集合,而且这些函数被授予特权,拥有使用或修改私有状态的能力。如果把seqer.gensym作为一个值传递给第三方函数,这个函数就能通过它产生唯一字符串,却不能通过它来改变prefix或seq的值。


  1. &;
相关文章
|
1月前
|
数据采集 JavaScript 前端开发
理解并应用:JavaScript响应式编程与事件驱动编程的差异
了解JavaScript的响应式编程与事件驱动编程至关重要。事件驱动编程基于事件触发函数执行,如用户交互或系统事件。响应式编程则关注数据流变化,利用Observables自动响应更新。在爬虫代理IP的Web Scraping示例中,两者分别通过axios和rxjs显示了数据抓取的不同处理方式。掌握这两者能提升异步操作的效率和代码质量。
理解并应用:JavaScript响应式编程与事件驱动编程的差异
|
1月前
|
JSON JavaScript 前端开发
Node.js命令大全:让你的编程效率翻倍
探索Node.js常用命令!本文作者木头左带你了解文件操作:`ls`、创建/删除文件夹、复制/移动文件及读写文件内容。此外,还介绍了查看系统信息、CPU和内存详情的方法。一起提升Node.js开发效率![[1](https://mutouzuo.oss-cn-hangzhou.aliyuncs.com/my/mudouzuo1.png)]
Node.js命令大全:让你的编程效率翻倍
|
20天前
|
JavaScript 前端开发
node.js 导入导出模块(CommonJS模块化规范,ES6模块化规范)
node.js 导入导出模块(CommonJS模块化规范,ES6模块化规范)
14 1
|
27天前
|
JavaScript 前端开发 NoSQL
JavaScript 启蒙之旅:探索编程世界的起点与基石
JavaScript 启蒙之旅:探索编程世界的起点与基石
|
1月前
|
JavaScript 前端开发
JavaScript进阶-Class与模块化编程
【6月更文挑战第21天】**ES6引入Class和模块化,提升JavaScript的代码组织和复用。Class是原型机制的语法糖,简化面向对象编程。模块化通过`import/export`管理代码,支持默认和命名导出。常见问题包括`this`指向和循环依赖。理解这些问题及避免策略,能助你写出更高效、可维护的代码。**
|
29天前
|
JSON JavaScript 前端开发
Javascript 模块化编程的方法和代码
Javascript 模块化编程的方法和代码
17 1
|
20天前
|
JavaScript 前端开发 API
JavaScript编码之路【ES6新特性之模块化】
JavaScript编码之路【ES6新特性之模块化】
14 0
|
20天前
|
JavaScript
js【详解】深拷贝 (含 JSON.parse(JSON.stringify(obj)) 的缺陷,5种手写深拷贝)
js【详解】深拷贝 (含 JSON.parse(JSON.stringify(obj)) 的缺陷,5种手写深拷贝)
8 0
|
24天前
|
人工智能 JavaScript 前端开发
JavaScript AI 编程助手
JavaScript AI 编程助手
21 0
|
25天前
|
JavaScript 前端开发 IDE
程序员必知:WPSJSA宏编程(JS):1.初识
程序员必知:WPSJSA宏编程(JS):1.初识
27 0