ホームページ >ウェブフロントエンド >jsチュートリアル >Javascript Memoizer_javascript スキルの簡単な分析

Javascript Memoizer_javascript スキルの簡単な分析

WBOY
WBOYオリジナル
2016-05-16 16:33:551243ブラウズ

以下は John Hann の実装からのもので、このコードはメソッド呼び出しの結果をキャッシュする賢い方法を使用しています。

コード分析:

コードをコピーします コードは次のとおりです:

// memoize: メモ化を使用したキャッシュの一般的な方法
// func: キャッシュされるメソッド
// コンテキスト: メソッド実行コンテキスト
// 注: メソッドは外部からアクセス可能であり、パラメーターは文字シリアル化可能である必要があります
function memoize (func, context) {
Function memoizeArg (argPos) { //パラメータは元のメソッド内のパラメータの位置を示します
var queue = {} //このキャッシュのキーはパラメータ、値は実行結果です
return function () { //関数クロージャを返します
If (argPos == 0) { //最初のパラメータ、キャッシュされたキーにパラメータが存在しない場合は、元の関数を実行し、実行結果を保存します
If (!(キャッシュ内の引数[argPos])) {
キャッシュ[引数[argPos]] = func.apply(コンテキスト, 引数);                                                                                                                       return キャッシュ[引数[argPos]];                                                                 Else {// が最初のパラメータではない場合、パラメータがキャッシュ キーに存在しない場合は、元のメソッド 1
内のパラメータの位置が再帰的に実行されます。 If (!(キャッシュ内の引数[argPos])) {
キャッシュ[引数[argPos]] = memoizeArg(argPos - 1);                                                                                                                       return queue[arguments[argPos]].apply(this, argument);                                                                 }
}
var arity = func.arity || func.length; // func パラメータの長さ、length 属性は JavaScript で使用され、arity 属性はその他で使用されます
Return memoizeArg(arity - 1) //最後のパラメータから再帰
}



使用:




コードをコピー

コードは次のとおりです:

var mem = memoize(func, this); アラート(mem.call(this,1,1,2)); アラート(mem.call(this,2,1,2)); アラート(mem.call(this,3,1,3)); alert(mem.call(this,2,2,4)); 単純なように見えますが、一見すると理解するのは簡単ではないかもしれませんが、クロージャの使用に慣れていれば、簡単に理解できるでしょう。上記の mem.call へのいくつかの呼び出しの後、ツリーが形成されます。各ノードはクロージャであり、各クロージャにはキャッシュがあり、各キャッシュのキーはツリー ブランチです。

(注: 上の図の「結果」もクロージャですが、argPos は 0 です)

しかし、方法はたくさんあります。たとえば、リンボーイは次のように言いました。


コードをコピー

コードは次のとおりです:


function Memoize(fn){
var キャッシュ = {}; 戻り関数(){
var key = []; for( var i=0, l = argument.length; i key.push(arguments[i]); If( !(キャッシュ内のキー) )
キャッシュ[キー] = fn.apply(this, argument); キャッシュを返す
};
}



実装はより単純ですが、パラメーターを配列にプッシュし、その配列をキーとして使用します。キーは文字列型のみをサポートするため、使用するときはこれに注意する必要があります (たとえば、オブジェクトtostring "[object Object]" の後にのみ表示されます)、その機能は上記のものよりも弱いです。
これを改善するのは難しくありません。パラメータ用に別のオブジェクトを作成するだけで、元のキャッシュ オブジェクトとこの別のパラメータ オブジェクトが ID に関連付けられます。

コードをコピーします

コードは次のとおりです: function Memoize(fn){ var キャッシュ = {}、引数 = {}; 戻り関数(){
for( var i=0, key = args.length; i If( 等しい( args[i], 引数 ) )
キャッシュを返す
}
args[キー] = 引数; キャッシュ[キー] = fn.apply(this, argument); キャッシュを返す
};
}



簡潔な関数メソッドとして記述できるメソッドは他にもあります。
声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。