這個世界需要一個特定的惡人,可以供人們指名道姓,千夫所指:“全都怪你”。
——村上春樹《當我談跑步時我談些什麼》
本文為讀 lodash 原始碼的第六篇,後續文章會更新到這個倉庫中,歡迎 star:pocket-lodash
gitbook也會同步倉庫的更新,gitbook地址:pocket-lodash
本篇分析的是 assocIndexOf
函式。
作用與用法
assocIndexOf
是 lodash 的內部函式,之前在《lodash原始碼分析之Hash快取》介紹過一種這樣的資料結構:
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--和--length
我們都知道自減還有另外一種前置的形式,即 --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
的時候,因此如果換成這種形式,會漏掉一次迴圈。
參考
License
署名-非商業性使用-禁止演繹 4.0 國際 (CC BY-NC-ND 4.0)
最後,所有文章都會同步傳送到微信公眾號上,歡迎關注,歡迎提意見:
作者:對角另一面