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

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