2

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
4

1 回答 1

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

对比

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)
};
于 2013-03-06T01:11:30.843 回答