以下はJohn Hannの実装からのものであり、このコードは私の注意を引きました。
コード解析:
コードコピーは次のとおりです。
//メモ:メモを使用してキャッシュする一般的な方法
// FUNC:キャッシュされる方法
//コンテキスト:メソッド実行コンテキスト
//注:メソッドは外部的にアクセス可能でなければならず、パラメーターは文字セリア化されています
function memoize(func、context){
function memoizearg(argpos){//パラメーターは、元のメソッドのパラメーターの位置を示します
var cache = {}; //このキャッシュのキーはパラメーターであり、値は実行結果です
return function(){//関数閉鎖を返します
if(argpos == 0){//最初のパラメーター、キャッシュキーにパラメーターが存在しない場合、元の関数が実行され、実行結果が保存されます
if(!(arguments [argpos] in cache)){
キャッシュ[arguments [argpos]] = func.apply(context、arguments);
}
キャッシュを返す[arguments [argpos]];
}
else {//最初のパラメーターではありません。キャッシュキーにパラメーターが存在しない場合、Memoizeargメソッドは再帰的に実行されます。元の方法のパラメーターの位置-1
if(!(arguments [argpos] in cache)){
キャッシュ[arguments [argpos]] = memoizearg(argpos -1);
}
キャッシュを返す[arguments [argpos]]。適用(this、arguments);
}
}
}
var arity = func.arity || func.length; // FUNCパラメーターの長さが使用され、Arity属性がJavaScriptで使用されます。
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));
アラート(mem.call(this、2,2,4));
簡単に思えますが、見ると理解するのは簡単ではありませんが、閉鎖の使用に精通している場合、理解しやすいでしょう。上記のmem.callへの呼び出しの後、ツリーが形成されます。各ノードは閉鎖であり、各閉鎖にはキャッシュがあり、各キャッシュキーはツリーブランチです。
(注:上の写真の「結果」も閉鎖ですが、Argposはわずか0です)
しかし、Limboyが言ったように、多くの方法があります:
コードコピーは次のとおりです。
function memoize(fn){
var cache = {};
return function(){
var key = [];
for(var i = 0、l = arguments.length; i <l; i ++)
key.push(arguments [i]);
if(!(キャッシュのキー))
キャッシュ[key] = fn.apply(this、arguments);
キャッシュを返す[key];
};
}
実装は簡単ですが、パラメーターを配列に押し込み、配列をキーとして扱うと、キーは文字列のみをサポートします。したがって、それを使用するときにこの点に注意を払う必要があります(たとえば、オブジェクトのtoStringの後、「[オブジェクトオブジェクト]」のみが表示される場合があります)。その機能は上記よりも弱いです。
これを改善することは難しくありません。パラメーターを使用して別のオブジェクトを設定するだけで、元のキャッシュオブジェクトとこの他のパラメーターオブジェクトはIDに関連付けられています。
コードコピーは次のとおりです。
function memoize(fn){
var cache = {}、args = {};
return function(){
for(var i = 0、key = args.length; i <key; i ++){
if(等しい(args [i]、arguments))
キャッシュを返す[i];
}
args [key] = arguments;
キャッシュ[key] = fn.apply(this、arguments);
キャッシュを返す[key];
};
}
簡潔な機能的方法として記述できる他の方法がいくつかあります。