使用函数和闭包去构建JavaScript模块

2015-09-05  本文已影响39人  LuckyJing

引言:全局变量是魔鬼,我们最好不要与它打交道;
使用闭包的好处是让函数自我管理,通过现有函数生成(return)新的更加实用的函数(闭包返回匿名函数)。

现在我们需要写一个函数,它的功能是将字符串中的HTML实体(例如<>)转换为相应的字符,输入是一个字符串,输出是一个新的字符串。我们可以很容易想到,创建一个字符映射表,根据正则表达式依次替换就可以了。思路很简单,我们尝试一下。

方案一

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

在全局作用域内生成了一个映射表entity,再在全局作用域内声明了函数实体,最后调用它,虽然能达到目的,但是的确不是好的结构风格,毕竟放那么多变量在全局作用域内,到最后是非常难以维护的。

方案二

var deentityify1 = function(str){
 //在函数内部声明了entity映射表,确保外界无法访问,避免污染
        var entity = {
            quot: '"',
            lt:'<',
            gt:'>'
        };
        return str.replace(/&([^&;]+);/g,function(a,b){
            var r = entity[b];
            return typeof r ==='string' ? r : a;
        });
    };

方案二将entity移动到了函数体内部,这样做可以避免一部分污染,可是我们仔细想一想,在这个函数调用结束之后,entity没有被任何变量所引用,所以它将会被回收,问题来了,在我大量调用这个函数时,将会伴随着entity的多次创建和回收。

方案三-使用闭包

var deentityify2 = function(){
        var entity = {
            quot: '"',
            lt:'<',
            gt:'>'
        };
        return function(str){
            if(str !== undefined){
                return str.replace(/&([^&;]+);/g,function(a,b){
                        var r = entity[b];
                        return typeof r ==='string' ? r : a;
                        }); 
            }else{
                return '请输入参数';
            }
        };
    }();//deentityify2函数实际上得到的是这个匿名函数的返回值

在创建这个函数时,加上()调用操作符来立即调用,本来entity应该在这个函数结束后被回收的,因为闭包的产生,使一个全局函数deentityify2通过引用一个匿名函数从而引用了entity,导致它并不会被回收,entity作为私有变量,只能通过特权函数deentityify2去访问,实现了信息隐藏。

上一篇下一篇

猜你喜欢

热点阅读