在TGP deentityify方法中引入的Javascript模块模式 - 为什么这种模式是必要的?

时间:2013-03-06 00:59:29

标签: javascript closures module-pattern

Crockford在deentityify方法中引入了一种模式来创建模块。他声称:

  

模块模式利用函数范围并关闭创建绑定和私有的关系。在此示例中,只有deentityify方法可以访问实体数据结构。

提取删除他的自定义函数,我认为代码归结为......

String.prototype.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;
        });  //close function(a,b)
    }; //close the returned function
} /* close  top level */ (); /* but evaluate it so deentitify becomes the returned fcn(!)

问题是我不明白为什么这个额外的间接层是必要的。这段代码不相同吗?

String.prototype.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;
        });  //close function(a,b)
//    }; //close the returned function
} /* close  top level, don't evaluate

1 个答案:

答案 0 :(得分:4)

此模式的基本原因是避免在每次通话时重新评估entity。将entity替换为构造成本高昂的东西,并且不会因呼叫而改变:

String.prototype.deentityify = function() {
    // expensiveFunctionCall is called *once* - when the function is defined.
    var entity = expensiveFunctionCall();

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

VS

String.prototype.deentityify = function() {
    // expensiveFunctionCall is called
    // *every time* "anyString".deentityify() is called.
    var entity = expensiveFunctionCall();

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