摘要:賦予了函數(shù)非常多的特性,其中最重要的特性之一就是將函數(shù)作為第一型的對象。那就意味著在中函數(shù)可以有屬性,可以有方法,可以享有所有對象所擁有的特性。參考資料忍者秘籍關(guān)于函數(shù)我之前還寫過一篇中高階函數(shù)的魅力有興趣的話可以看一看。
Javascript賦予了函數(shù)非常多的特性,其中最重要的特性之一就是將函數(shù)作為第一型的對象。那就意味著在javascript中函數(shù)可以有屬性,可以有方法, 可以享有所有對象所擁有的特性。并且最重要的,她還可以直接被調(diào)用
我們簡單的試驗(yàn)一下就可以發(fā)現(xiàn)
// 簡單實(shí)驗(yàn) 函數(shù)作為對象的存在 let fn = function () {} fn.prop = "fnProp" console.log(fn.prop) // fnProp
為函數(shù)添加屬性的這個特性我覺的大家在平時的開發(fā)中基本沒什么嘗試或者是使用過,但是在一些JS庫或者是事件回掉管理中都能發(fā)揮出很大的用處。下面一起來看幾個例子。
函數(shù)緩存在某有一些的情況下我們可以要存儲一組相關(guān)但是相互又獨(dú)立的函數(shù)。這個需求看起來很easy,實(shí)現(xiàn)起來也不復(fù)雜。最顯而易見的做法是使用一個數(shù)組來保存所有的函數(shù),
這樣不是不可以,但是顯然這種做法不是最好的。下面通過為函數(shù)屬性我們呢來實(shí)現(xiàn)這個我們的目的
// 1:函數(shù)緩存示例 let store = { nextId: 1, // id cache: {}, // 緩存 add (fn) { // 如果函數(shù)中沒有id屬性那么就緩存 if (!fn.id) { console.log(`begin add func ${fn.name}`) fn.id = store.nextId ++ // 設(shè)置完緩存之后返回true return !!(store.cache[fn.id] = fn) } else { console.log(`${fn.name} is already in cache`) } } } function storeCache() {} store.add(storeCache) // begin add func storeCache store.add(storeCache) // storeCache is already in cache
上面的這一段代碼邏輯清晰,store對象用來管理我們的緩存,cache屬性用來存儲函數(shù),nextId屬性用來保存當(dāng)前的緩存Id,add()方法用來設(shè)置存儲,先來判斷當(dāng)前函數(shù)是否已經(jīng)在緩存中然后再去設(shè)置緩存,這樣就能限制函數(shù)的重復(fù)添加,最后返回true。
!!構(gòu)造是一種可以將任意Javascript表達(dá)式轉(zhuǎn)化為其等效布爾值的簡單方式。緩存記憶函數(shù)
這種函數(shù)可以記住之前已經(jīng)計(jì)算過的結(jié)果,避免了不必要的計(jì)算,這顯然是能夠提升代碼性能的。
在舉例之前我們先來看看這種方式的優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
緩存了之前的結(jié)果,最終用戶享有性能優(yōu)勢
實(shí)際上是發(fā)生在幕后,操作無感
缺點(diǎn)
內(nèi)存的犧牲這是肯定的
打破了存粹性(一個函數(shù)或者方法應(yīng)該只做好一件事)
如果方法中有算法,那么很難測量這個算法的性能
了解了優(yōu)缺點(diǎn)我們來看一個簡單的計(jì)算素?cái)?shù)的例子(不是很嚴(yán)謹(jǐn))
// 2: 緩存記憶函數(shù) function isPrime (value) { if (!isPrime.anwers) isPrime.anwers = {} // 先從緩存里面取 if (isPrime.anwers[value] != null ) { return isPrime.anwers[value] } // 開始進(jìn)行判斷和計(jì)算 let prime = value != 1 for (let index = 2; index < value; index++) { if (value % index == 0) { prime = false break; } } // 保存計(jì)算出來的值 return isPrime.anwers[value] = prime } console.log(isPrime(5)) console.log(`從函數(shù)記憶中直接讀取${isPrime.anwers[5]}`)
這里呢 好處是特別明顯的我們再次的取用isPrime.anwers[5]的時候不需要經(jīng)過任何的計(jì)算,但是大型的計(jì)算要主要內(nèi)存的使用
緩存記憶DOM元素通過元素的標(biāo)簽查詢DOM的操作的的代價是昂貴的,各位前端大佬肯定都很清楚。我們下面使用緩存記憶的方式來進(jìn)行這個操作
// 3:緩存記憶DOM元素 function getElements (name) { if (!getElements.cache) getElements.cache = {} return getElements.cache[name] = getElements.cache[name] || document.getElementsByTagName(name); } console.log(getElements("div")) // HTMLCollection console.log(getElements.cache["div"]) // HTMLCollection
這個函數(shù)和上面的緩存使用的同一個手法,而且這簡單的4句代碼能為我們的性能帶來大幅度的提升。這也算是一種超能力吧。函數(shù)的很多特性都和其上下文有關(guān),接下來我們研究一個和上下文又換的例子。
偽造數(shù)組方法(上下文相關(guān))在一些情況下我們想創(chuàng)建一個包含一組數(shù)據(jù)的對象,但是這個數(shù)據(jù)包含很多的狀態(tài),比如和集合項(xiàng)有關(guān)的元數(shù)據(jù)那么我們用數(shù)組來存就不太合適了。那么這里我們就用對象的方式來假扮數(shù)組。通過改變上下文來完成一些“不法的行為”
// 4:偽造數(shù)組方法 // // let elems = { length: 0, //為了保存?zhèn)€數(shù) add (elem) { Array.prototype.push.call(this, elem) }, gather (id) { this.add(document.getElementById(id)) } } elems.gather("add") elems.gather("remove") console.log(elems[0]); // console.log(elems[1]); // console.log(elems.length); // 2 console.log(elems); /** 0: input#add 1: input#remove add: ? add(elem) gather: ? gather(id) length: 2 */
在我還對JS懵懵懂懂的時候看到這樣的操作被秀了一臉,簡直是刺激了我幼小的心靈。
我們在add函數(shù)中實(shí)現(xiàn)了把元素添加到了集合中,而且Array又正好提供push方法, 不用白不用。這種操作也是直白的展示了函數(shù)上下文的超強(qiáng)特性。
總結(jié)Javascript強(qiáng)大的靈活性, 也帶來更多的可能性。 路漫漫其修遠(yuǎn)兮,吾將上下而求索。
參考資料: 《JavaScript忍者秘籍》
關(guān)于函數(shù)我之前還寫過一篇JavaScript中高階函數(shù)的魅力, 有興趣的話可以看一看。
代碼地址
原文地址 如果覺得有幫助的得話給個?吧
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/103365.html
摘要:上傳進(jìn)度下面通過高階函數(shù)的方式我們來實(shí)現(xiàn)函數(shù)節(jié)流節(jié)流函數(shù)計(jì)時器是否是第一次調(diào)用首次調(diào)用直接放行存在計(jì)時器就攔截設(shè)置使用節(jié)流分時函數(shù)節(jié)流函數(shù)為我們提供了一種限制函數(shù)被頻繁調(diào)用的解決方案。 高階函數(shù)是指至少滿足下列條件之一的函數(shù) 1:函數(shù)可以作為參數(shù)被傳遞 2:函數(shù)可以作為返回值輸出 JavaScript語言中的函數(shù)顯然的是滿足了高階函數(shù)的條件,下面我們一起來探尋JavaScript種高階...
摘要:前言由于最近的項(xiàng)目用到了一些的代碼,所以我?guī)е闷嫘?,認(rèn)真閱讀了這本書,粗略地了解語言的基本結(jié)構(gòu)和特性,對于一些不熟悉的新概念,以記錄的形式加強(qiáng)印象,也是對學(xué)習(xí)的反思總結(jié)。 前言 由于最近的項(xiàng)目用到了一些js的代碼,所以我?guī)е闷嫘?,認(rèn)真閱讀了這本書,粗略地了解js語言的基本結(jié)構(gòu)和特性,對于一些不熟悉的新概念,以記錄的形式加強(qiáng)印象,也是對學(xué)習(xí)的反思總結(jié)。 一、字面量(literals...
摘要:在函數(shù)式編程的組合中,我們是從右到左執(zhí)行的,上述的例子中我們借助函數(shù)實(shí)現(xiàn)組合,當(dāng)然,我們也可以用自己的方式實(shí)現(xiàn)。小結(jié)函數(shù)式編程隨著多核的發(fā)展,開始再次出現(xiàn)在我們的視野中,有時候也會擔(dān)心過于吹捧函數(shù)式,反而落入俗套。 程序的本質(zhì)是什么?數(shù)據(jù)結(jié)構(gòu)+算法?。?!我想這也是很多程序員給出的答案,我自己也認(rèn)可這一觀點(diǎn),當(dāng)我們了解了某一門編程語之后,接下來我們面對的往往是數(shù)據(jù)結(jié)構(gòu)和算法的學(xué)習(xí)。而現(xiàn)在...
摘要:,微軟發(fā)布,同時發(fā)布了,該語言模仿同年發(fā)布的。,公司在瀏覽器對抗中沒落,將提交給國際標(biāo)準(zhǔn)化組織,希望能夠成為國際標(biāo)準(zhǔn),以此抵抗微軟。同時將標(biāo)準(zhǔn)的設(shè)想定名為和兩類。,尤雨溪發(fā)布項(xiàng)目。,正式發(fā)布,并且更名為。,發(fā)布,模塊系統(tǒng)得到廣泛的使用。 前言 作為程序員,技術(shù)的落實(shí)與鞏固是必要的,因此想到寫個系列,名為 why what or how 每篇文章試圖解釋清楚一個問題。 這次的 why w...
摘要:今天這篇文章主要介紹函數(shù)式編程的思想。函數(shù)式編程通過最小化變化使得代碼更易理解。在函數(shù)式編程里面,組合是一個非常非常非常重要的思想??梢钥吹胶瘮?shù)式編程在開發(fā)中具有聲明模式。而函數(shù)式編程旨在盡可能的提高代碼的無狀態(tài)性和不變性。 最開始接觸函數(shù)式編程的時候是在小米工作的時候,那個時候看老大以前寫的代碼各種 compose,然后一些 ramda 的一些工具函數(shù),看著很吃力,然后極力吐槽函數(shù)式...
閱讀 2606·2021-11-18 10:02
閱讀 2638·2021-11-15 11:38
閱讀 3717·2021-11-12 10:36
閱讀 708·2021-11-12 10:34
閱讀 2907·2021-10-21 09:38
閱讀 1496·2021-09-29 09:48
閱讀 1507·2021-09-29 09:34
閱讀 1102·2021-09-22 10:02