js高手進階之路:underscore原始碼經典(二)

亞里士朱德發表於2015-10-18

先看一下兩個比較重要的內部函式

這個函式是underscore內部很重要的函式,主要用來執行函式並改變所執行函式的作用域,最後加了一個argCount引數來指定引數個數,對引數個數小於等於4的情況進行分類處理。對不同引數的解釋大概是:
1的情況一般是用在接受單值的情況,比如times,sortedIndex之類的函式。
2的情況據說是給比如jQuery,zepto事件繫結,代理什麼的,但是在原始碼中沒有看到被呼叫。
3的情況用於迭代器函式,比如foreach,map,pick等。
4的情況用reduce和reduceRight函式。

這也是一個比較常用的內部函式,只是對引數進行了判斷:如果是函式則返回上面說到的回撥函式;如果是物件則返回一個能判斷物件是否相等的函式;預設返回一個獲取物件屬性的函式。

從程式碼上看,each函式是包括map函式的,map只能處理物件,each可以處理物件和陣列。至於forEach和collect在API文件中看不到,應該是為了相容以前老版本做的別名處理。

這個是reduce和reduceRight呼叫的內部函式,將memo這個變數作為入參傳遞給iterator函式,呼叫自定義的iteratee函式進行迴圈處理,每次處理完的結果都賦值給memo變數,最後返回memo變數的結果。這裡有兩個問題

  • 為什麼這裡不按照常理邏輯來寫程式碼而要用閉包呢?閉包大致有這麼幾個作用:避免命名衝突;私有化變數;變數持久化。這裡的作用主要就是變數(函式)持久化,好處就是重複呼叫的時候不需要再重新建立函式,從而提升執行速度。
  • 為什麼要用兩層閉包呢?第一層閉包持久化iterator函式,呼叫reduce和reduceRight函式避免重複新建函式。第二層閉包儲存keys,index,length這些變數。

    這裡用slice.call(arguments, 2)來獲取後面的不定引數,然後用func.apply(value, args)來傳入該引數比較有意思。

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

任選一種支付方式

js高手進階之路:underscore原始碼經典(二) js高手進階之路:underscore原始碼經典(二)

相關文章