這個世界須要一個特定的惡人,能夠供人們指名道姓,千夫所指:「全都怪你」。javascript
——村上春樹《當我談跑步時我談些什麼》html
本文爲讀 lodash 源碼的第六篇,後續文章會更新到這個倉庫中,歡迎 star:pocket-lodashjava
gitbook也會同步倉庫的更新,gitbook地址:pocket-lodashgit
本篇分析的是 assocIndexOf
函數。github
assocIndexOf
是 lodash 的內部函數,以前在《lodash源碼分析之Hash緩存》介紹過一種這樣的數據結構:express
var caches = [['test1', 1],['test2',2],['test3',3]]
這是一個二維數組,每項中的第一項做爲緩存對象的 key
,第二項爲緩存的值。數組
assocIndexOf
的做用是找出指定的 key
在數組中的索引值。緩存
例如要找 key
爲 tes1
的索引 :微信
assocIndexOf(caches, 'test1') // 0
import eq from '../eq.js'
function assocIndexOf(array, key) { let { length } = array while (length--) { if (eq(array[length][0], key)) { return length } } return -1 }
這段代碼很精簡,讓 length
自減,調用 eq
函數,從二維數組的最後一項開始,逐項獲取 key
值,與傳入的 key
比較,遇到匹配的,立刻將該項的索引返回。若是都沒找到,返回 -1
。返回結果的規則與 indexOf
一致。
咱們都知道自減還有另一種前置的形式,即 --length
,那將上面的代碼改爲 while(--length)
可不能夠呢?試一下就知道了。
改了以後,用 caches
來測試下:
assocIndexOf(caches, 'test3') // 2 assocIndexOf(caches, 'test2') // 1 assocIndexOf(caches, 'test1') // -1
能夠看到,改了以後,隻影響到了第一項的結果,也就是終止條件有問題,根本沒有遍歷到第一項,可是後面的結果是正確的,也就說循環體裏的 length
沒有受到影響。
你可能會有點疑惑,while
的終止條件比較的不是 length
嗎?爲何 length--
正確,而 --length
不正確呢?
其實 while
的終止條件並非 length
,而是 length--
表達式所返回的結果。如今來看一下 length--
和 --length
所返回的結果有什麼差異。
var length = 3 length-- // 3 length // 2
能夠看到, length--
返回的結果和自減前的一致,可是 length
已經減小 1
了。所以使用 length--
,最後一次進入循環體應該在 length
等於 1
的時候。
再來看 --length
var length = 3 --length // 2 length // 2
--length
返回的結果跟自減後的結果一致,所以最後一次進入循環體應該是 length
爲 2
的時候,所以若是換成這種形式,會漏掉一次循環。
署名-非商業性使用-禁止演繹 4.0 國際 (CC BY-NC-ND 4.0)
最後,全部文章都會同步發送到微信公衆號上,歡迎關注,歡迎提意見:
做者:對角另外一面