函數(shù)式編程之記憶
是一種時間換空間的方法,用犧牲空間的復(fù)雜度來換取時間的復(fù)雜度
function f() { var s = arguments.length + Array.prototype.join.call(arguments); console.log(s); };
這里使用的是Array.prototype.join方法進(jìn)行字符串連接
返回的是連接的結(jié)果
// 這是一個用于返回f()的帶有記憶功能的函數(shù) 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); }; }
這是一個具有記憶的函數(shù),用數(shù)組的長度和數(shù)組合并后組成的字符串作為屬性名,進(jìn)行保存,如果這個值存在則直接進(jìn)行保存,如果值不存在則進(jìn)行保存并返回(因?yàn)橘x值語句會返回右值,所以return語句后無需再跟進(jìn)行返回值的語句)
使用調(diào)試函數(shù)對其進(jìn)行修改// 這是一個用于返回f()的帶有記憶功能的函數(shù) 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); }; }; }
這樣就更加的明顯了
使用這個函數(shù)返回兩個整數(shù)的最大公約數(shù)
歐幾里得算法
由歐幾里得最先發(fā)現(xiàn),一個用于計算最大公因數(shù)的算法
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; }
利用歐幾里得算法寫的求兩個數(shù)的最大公因數(shù),運(yùn)行一下
gcd(85, 187); 17
計算結(jié)果正確,使用剛剛實(shí)現(xiàn)的具有記憶功能的高階函數(shù),將函數(shù)傳進(jìn)去,生成了一個新的函數(shù)
var functiongcd = memorize(gcd); Object { }
使用這個函數(shù)
好吧。莫名進(jìn)行死循環(huán)了。
Error: Script terminated by timeout at: gcd@Scratchpad/1:35:9 memorize/<@Scratchpad/1:24:27 @debugger eval code:1:1
沒辦法繼續(xù)排查錯誤
排查錯誤// 這是一個用于返回f()的帶有記憶功能的函數(shù) 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); }; }; }
這個函數(shù)依舊寫錯了,call只能傳入一個值,而apply能傳入多個值
繼續(xù)運(yùn)行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);
好啦,非常明顯,第一步是先將值緩存進(jìn)入其私有變量,即保存進(jìn)入閉包內(nèi)部,然后第二個是發(fā)現(xiàn)這個值已經(jīng)保存過了直接輸出
(^o^)/,
js的記憶折騰完畢~
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/96182.html
摘要:難怪超過三分之一的開發(fā)人員工作需要一些知識。但是隨著行業(yè)的飽和,初中級前端就業(yè)形勢不容樂觀。整個系列的文章大概有篇左右,從我是如何成為一個前端工程師,到各種前端框架的知識。 為什么 call 比 apply 快? 這是一個非常有意思的問題。 作者會在參數(shù)為3個(包含3)以內(nèi)時,優(yōu)先使用 call 方法進(jìn)行事件的處理。而當(dāng)參數(shù)過多(多余3個)時,才考慮使用 apply 方法。 這個的原因...
摘要:難怪超過三分之一的開發(fā)人員工作需要一些知識。但是隨著行業(yè)的飽和,初中級前端就業(yè)形勢不容樂觀。整個系列的文章大概有篇左右,從我是如何成為一個前端工程師,到各種前端框架的知識。 為什么 call 比 apply 快? 這是一個非常有意思的問題。 作者會在參數(shù)為3個(包含3)以內(nèi)時,優(yōu)先使用 call 方法進(jìn)行事件的處理。而當(dāng)參數(shù)過多(多余3個)時,才考慮使用 apply 方法。 這個的原因...
摘要:為此決定自研一個富文本編輯器。例如當(dāng)要轉(zhuǎn)化的對象有環(huán)存在時子節(jié)點(diǎn)屬性賦值了父節(jié)點(diǎn)的引用,為了關(guān)于函數(shù)式編程的思考作者李英杰,美團(tuán)金融前端團(tuán)隊(duì)成員。只有正確使用作用域,才能使用優(yōu)秀的設(shè)計模式,幫助你規(guī)避副作用。 JavaScript 專題之惰性函數(shù) JavaScript 專題系列第十五篇,講解惰性函數(shù) 需求 我們現(xiàn)在需要寫一個 foo 函數(shù),這個函數(shù)返回首次調(diào)用時的 Date 對象,注意...
摘要:之前有朋友問怎么去理解原型和原型鏈的問題。理解原型鏈的小技巧將箭頭視作泛化子類到父類關(guān)系那么圖中所有的虛線將構(gòu)成一個繼承層級,而實(shí)線表示屬性引用。原型鏈?zhǔn)菍?shí)現(xiàn)繼承的重要方式,原型鏈的形成是真正是靠而非。 之前有朋友問怎么去理解原型和原型鏈的問題。這個問題,在面試中,很多同學(xué)經(jīng)常都會遇到。這里給大家講講,方便大家記憶。 JavaScript的特點(diǎn)JavaScript是一門直譯式腳本...
摘要:之前有朋友問怎么去理解原型和原型鏈的問題。理解原型鏈的小技巧將箭頭視作泛化子類到父類關(guān)系那么圖中所有的虛線將構(gòu)成一個繼承層級,而實(shí)線表示屬性引用。原型鏈?zhǔn)菍?shí)現(xiàn)繼承的重要方式,原型鏈的形成是真正是靠而非。 之前有朋友問怎么去理解原型和原型鏈的問題。這個問題,在面試中,很多同學(xué)經(jīng)常都會遇到。這里給大家講講,方便大家記憶。 JavaScript的特點(diǎn)JavaScript是一門直譯式腳本...
閱讀 1531·2021-09-22 15:52
閱讀 1623·2019-08-30 15:44
閱讀 956·2019-08-30 14:24
閱讀 2762·2019-08-30 13:06
閱讀 2770·2019-08-26 13:45
閱讀 2840·2019-08-26 13:43
閱讀 1084·2019-08-26 12:01
閱讀 1579·2019-08-26 11:56