码迷,mamicode.com
首页 > 编程语言 > 详细

[javascript] 使用闭包编写模块

时间:2015-03-11 18:39:04      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:

这是一篇[javascript the good parts]的读书笔记。

我们知道可以利用javascript 的prototype 特性为原始类型编写拓展模块。利用如下方法:

Object.prototype.method = function(name, func) {
    Object.prototype[name] = func
}

为javascript 里的所有对象添加一个便捷的扩展方法method. 这个便捷方法省去了我们每次都手工输入Object.prototype.xxxx

现在我们要为string 类型添加一个拓展方法,叫做deentityify,作用是把形如 < 或者 &qout; 这样的字符串替换成他原来的样子。

很自然的,我们需要一个存着替换规则的表:

var entity = {
    qout: ‘"‘,
    lt: ‘<‘,
    gt: ‘>‘
}

但是现在的问题是,这个表应该让他存在哪呢?

方案1.存在全局变量里。

方案2.就存在deentityify 这个函数里。

方案1不可行?,因为全局变量是邪恶的?? 我们应该尽量避免使用全局变量。

那就试试方案2:

String.method(‘deentityify‘, function(){
    var entity = {
        quot: ‘"‘,
        lt: ‘<‘,
        gt: ‘>‘
    }

    return this.replace(/&[^&;]+);/g, function(a, b) {
        var r = entity[b];
        return typeof r === ‘string‘ ? r : a;
    })
})


var s = "&lt;&quot;&gt;"
s.deentityify()  //<">

结果是正确的,但是有个问题,每次调用deentityify 的时候,entity 都被求值一次,这显然会增加开销。

看来方案2也不是最理想的,有没有什么规避的方法呢?设想,如果让entity 只求值一次,然后把他的结果保存下来,以后每次调用deentityify 的时候直接使用entity的结果,而不是每次调用都去把他再求值一次。这可以做到吗?

当然可以,答案就是使用闭包:

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

相比方案2直接返回结果,闭包的方案是返回一个函数,然后立即对他求值,求值的结果作为deentityify 的值。

感觉有点绕,但是这样的一个好处是,entity 只在String.method() 这里被求值,以后,每次用deentityify 的时候,我们都只是直接使用entity 的值,而不用每次都求值了。这就是闭包的威力。

[javascript] 使用闭包编写模块

标签:

原文地址:http://www.cnblogs.com/agentgamer/p/4330258.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!