函數式編程之記憶
是一種時間換空間的方法,用犧牲空間的復雜度來換取時間的復雜度
function f() { var s = arguments.length + Array.prototype.join.call(arguments); console.log(s); };
這里使用的是Array.prototype.join方法進行字符串連接
返回的是連接的結果
// 這是一個用于返回f()的帶有記憶功能的函數 function memorize(f) { var cacho = {}; // 定義一個用于保存值的私有變量 return function() { var key = arguments.length + Array.prototype.join.call(arguments, ","); if (key in cacho) return cacho[key]; else return cacho[key] = f.call(this, arguments); }; }
這是一個具有記憶的函數,用數組的長度和數組合并后組成的字符串作為屬性名,進行保存,如果這個值存在則直接進行保存,如果值不存在則進行保存并返回(因為賦值語句會返回右值,所以return語句后無需再跟進行返回值的語句)
使用調試函數對其進行修改// 這是一個用于返回f()的帶有記憶功能的函數 function memorize(f) { var cacho = {}; // 定義一個用于保存值的私有變量 console.log(cacho); return function() { var key = arguments.length + Array.prototype.join.call(arguments, ","); console.log(key); if (key in cacho) { console.log(cacho[key]); return cacho[key]; } else { console.log(f.call(this,arguments)); return cacho[key] = f.call(this, arguments); }; }; }
這樣就更加的明顯了
使用這個函數返回兩個整數的最大公約數
歐幾里得算法
由歐幾里得最先發現,一個用于計算最大公因數的算法
function gcd(a, b) { var t; // 用于保存中間變量 if(a < b) // 確保 a >= b t = a, a = b, b = t; while(t != 0) t = a % b, a = b, b = t; return a; }
利用歐幾里得算法寫的求兩個數的最大公因數,運行一下
gcd(85, 187); 17
計算結果正確,使用剛剛實現的具有記憶功能的高階函數,將函數傳進去,生成了一個新的函數
var functiongcd = memorize(gcd); Object { }
使用這個函數
好吧。莫名進行死循環了。
Error: Script terminated by timeout at: gcd@Scratchpad/1:35:9 memorize/<@Scratchpad/1:24:27 @debugger eval code:1:1
沒辦法繼續排查錯誤
排查錯誤// 這是一個用于返回f()的帶有記憶功能的函數 function memorize(f) { var cache = {}; console.log(cache); return function() { var key = arguments.length + Array.prototype.join.call(arguments); console.log(key); if (key in cache) { console.log(cache[key]); return cache[key]; } else { console.log(f.apply(this,arguments)); return cache[key] = f.apply(this, arguments); }; }; }
這個函數依舊寫錯了,call只能傳入一個值,而apply能傳入多個值
繼續運行gcdmemo(85, 187); 285,187 Scratchpad/1:17:4 17 Scratchpad/1:23:7 17
其中第一個Scratchpad/1:17:4返回指代的是
if (key in cache) { console.log(cache[key]); return cache[key]; }
其中第二個Scratchpad/1:23:7返回指代的是
return cache[key] = f.apply(this, arguments);
好啦,非常明顯,第一步是先將值緩存進入其私有變量,即保存進入閉包內部,然后第二個是發現這個值已經保存過了直接輸出
(^o^)/,
js的記憶折騰完畢~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/96182.html
摘要:為此決定自研一個富文本編輯器。例如當要轉化的對象有環存在時子節點屬性賦值了父節點的引用,為了關于函數式編程的思考作者李英杰,美團金融前端團隊成員。只有正確使用作用域,才能使用優秀的設計模式,幫助你規避副作用。 JavaScript 專題之惰性函數 JavaScript 專題系列第十五篇,講解惰性函數 需求 我們現在需要寫一個 foo 函數,這個函數返回首次調用時的 Date 對象,注意...
摘要:之前有朋友問怎么去理解原型和原型鏈的問題。理解原型鏈的小技巧將箭頭視作泛化子類到父類關系那么圖中所有的虛線將構成一個繼承層級,而實線表示屬性引用。原型鏈是實現繼承的重要方式,原型鏈的形成是真正是靠而非。 之前有朋友問怎么去理解原型和原型鏈的問題。這個問題,在面試中,很多同學經常都會遇到。這里給大家講講,方便大家記憶。 JavaScript的特點JavaScript是一門直譯式腳本...
摘要:之前有朋友問怎么去理解原型和原型鏈的問題。理解原型鏈的小技巧將箭頭視作泛化子類到父類關系那么圖中所有的虛線將構成一個繼承層級,而實線表示屬性引用。原型鏈是實現繼承的重要方式,原型鏈的形成是真正是靠而非。 之前有朋友問怎么去理解原型和原型鏈的問題。這個問題,在面試中,很多同學經常都會遇到。這里給大家講講,方便大家記憶。 JavaScript的特點JavaScript是一門直譯式腳本...
閱讀 1418·2021-09-22 15:52
閱讀 1458·2019-08-30 15:44
閱讀 895·2019-08-30 14:24
閱讀 2705·2019-08-30 13:06
閱讀 2700·2019-08-26 13:45
閱讀 2782·2019-08-26 13:43
閱讀 1014·2019-08-26 12:01
閱讀 1436·2019-08-26 11:56