Underscore.js 入門教程

吳鵬煜發表於2016-08-18

Underscore.js 是一個由 Jeremy Ashkenas 開發的 JavaScript 庫,它提供了許多作為開發者的我們在開發 Web 專案所需要的實用功能。

它使程式碼變得更加易讀:

它使程式碼更容易編寫:

它提供了原生所沒有的方法:

它自身甚至可以作為模板引擎:

Underscore 是一個輕量級的庫(minify和gzip壓縮後只有5.7 kb),並且被許多知名專案所用,如:

現在我們開始更具體,更深入的討論它的主要功能。

重要部分

在本教程中,我要強調 Underscored 的三個最常用的方法:

我將分別解釋它們是如何使用,然後用它們一起編寫一個 Demo,Demo 你可以找到在教程最後找到。與以往一樣,這個 Demo 的程式碼會放在 Github 上。

如果你想跟著例子練習,你需要一份 Underscore 庫。你可以從,比如你所喜愛的 CDN 處獲取:

一路走來如果發現自己需要幫助,或者你想要了解更多,不要忘了還有內容更廣泛的 Underscore官方文件。它還有一個龐大而活躍的社群,意味著很容易得到其他人幫助。

_.each:寫看得懂的迴圈

任何一個專案都會有類似於此片段的程式碼:

Underscore 能夠使你用更具可讀性的方式編寫像這樣的程式碼,:

很贊不是嗎?_.each()接受兩個引數:

  • 需要遍歷的 Array(或者Object)
  • 回撥函式

對於 Array 中每一個元素(文件中稱為 iteratee ),_.each()都將呼叫回撥函式。在回撥函式中我們可以訪問三個引數:

  • 當前迭代的陣列元素(artist)的值。例如,對於上面的程式碼段,在第一次迭代我們會得到“Pharrel Williams”這個值
  • 當前迭代的序號(索引),在我們的這個例子下,是從0到2的數
  • 被迭代的陣列本身(artists

正如你所看到這樣,程式碼更易讀,我們不需要像之前提到的for迴圈那樣使用artist[i]就可以輕鬆訪問陣列中的各個元素。

See the Pen _.each by SitePoint (@SitePoint) on CodePen.

_.template: 簡單直白

由於單頁應用的興起,一個可靠的前端模板引擎已經成為工作棧中基本的需要。

Underscore 提供了一個模板引擎,這對於那些熟悉如 PHP 或 Ruby on Rails 語言的人來說可能非常熟悉。

從我們上面的程式碼片段繼續,我們來演示_.template()是如何工作的。新增如下幾行程式碼

在這裡,我們用一個字串引數來呼叫_.template()函式,這個引數包括用分隔符包含的一些資料(<%= artist%>)。當以這種方式呼叫_.template()的時候,會返回一個可複用的函式。

來呼叫我們的新函式artistTemplate(),傳遞文字作物件為引數,會返回我們最初傳遞到_.template()的字串,但是其中的自由變數會被引數中相應的值替代。在這個例子下<%=artist%>會被引數中artist的值所取代。

Underscore 的模板引擎不僅可以替換值,而且模板內部的指令碼也可以被執行。只需一處修改,這一段程式碼就可以如虎添翼。

我們已經把對_.each()的呼叫整合進模板,這使我們改變模板的呼叫方式。既然我們現在在_.template()函式中進行迭代,我們可以把整個的artists陣列傳入artistTemplate()(之前傳遞的是單個artist)。此程式碼輸出結果與前面的例子相同。

當需要_.template()eval其中的 JavaScript 程式碼時,需要用<%%>來包圍程式碼,而不是<%=%>

既然呼叫由_.template生成的模板和呼叫一個函式效果相同,我們可以用<%%>標籤把程式碼進一步改良。我們對artists設計一個外層模板,並且由它來呼叫為每個元素設計的內層模板,這樣子模板就是可複用的。

See the Pen _.template() by SitePoint (@SitePoint) on CodePen.

最後,來看看_.filter()函式。

_.filter():只需要一個布林函式

_.filter()接收一個陣列和一個回撥函式作為引數。然後它會對陣列中的每個元素呼叫回撥函式,然後返回一個新陣列,其中包含每個回撥函式執行後返回真值的元素。

回撥函式也像_.each()一樣接受三個引數:當前被遍歷的元素值,被遍歷值的索引,和陣列本身。

為了說得更明白,我們對程式碼做幾處修改。

你可能已經猜到了,在模板中只會收到['ACDC']作為陣列引數。這是我們目前的 demo 。

See the Pen _.filter() by SitePoint (@SitePoint) on CodePen.

說了那麼多。我們來做一些更有意義的東西。

Demo應用

不要忘了這個 Demo 的程式碼可以在Github 上找到。

我們將建立一個小程式,它呼叫其他 API,展示所拉取的資訊,並允許使用者過濾顯示。為此,我們將使用:

具體來說,這個程式將會從Spotify獲取一些藝人資訊,並通過使用Underscore的_.template,_.each和_.filter來展示,使用者可以根據流派來縮小展示範圍。

要做到這一點,我們將程式碼分為三個不同的模組:

_isAwesome.Config:儲存整個程式中將用到的資訊。
_isAwesome.Template:負責模板的編譯
_isAwesome:主模組,負責響應使用者操作並更新介面。

以上都遵循模組模式。
Config模組
該模組包含了要使用的模板的ID,還有用於查詢的 API 地址,還包括我們想從 Spotify 的查詢的藝人ID。通過這種方式,我們可以只需要在陣列中新增元素就可以查詢更多藝人的資訊。

Template模組
該模組通過呼叫Config模組中的getTemplates()來編譯模板。

主模組
該模組負責向Config模組取得的 URL 傳送 Ajax 請求,並且使用我們從Template模組中取得的模板渲染頁面。 除此之外,這個模組也負責響應使用者操作而過濾相應內容。

兩個過濾器和模板都會嵌入在 HTML 中。

為了實現過濾,我們將依賴HTML 5的data屬性和jQuery的data介面。這是為了方便起見,但你如果想著如何用原生實現的話,瀏覽器對這個介面的支援非常好。

這是用來做過濾按鈕的程式碼:

這是用來傳給過濾函式的物件的例子:

我們把模板放在標籤內,將其作為index.html的一部分。但是為了防止它被執行,需要將其type屬性設定為text/javascript以外的值。統一起見我們設定為underscore/template

我們將有兩個模板。第一個是藝人列表的模板,第二個是藝人單獨顯示時的模板。如上面所說,我們將其稱之為嵌入式模板。我們會從一個模板中('item-list')呼叫另一個模板('item-tpl')

然後,在該檔案的底部,我們會引入所需的庫和這三個指令碼。此外,為了使其更具視覺吸引力,我們還在header里加入了一些基本樣式。 And that’s it. 就是這樣。

See the Pen Underscore Awesomeness by SitePoint (@SitePoint) on CodePen.

總結

如我演示,Underscore 用起來十分賞心悅目,你可以寫出乾淨,可讀性強,並且容易維護的程式碼。

還有更多的內容可以加入我們這個 demo 裡(比如用_.pluck()來動態生成模板),但我覺得作為入門這些已經足夠。

你呢,你是否曾經用過 Underscore ,你是否會願意嘗試,你是否嘗試過其他功能相似的替代品(比如loadsh),評論告訴我吧。