日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Underscore.js常用方法介绍

發布時間:2023/12/13 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Underscore.js常用方法介绍 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Underscore.js是一個很精干的庫,壓縮后只有4KB。它提供了幾十種函數式編程的方法,彌補了標準庫的不足,大大方便了JavaScript的編程。MVC框架Backbone.js就將這個庫作為自己的工具庫。除了可以在瀏覽器環境使用,Underscore.js還可以用于Node.js。

Underscor.js定義了一個下劃線(_)對象,函數庫的所有方法都屬于這個對象。這些方法大致上可以分成:集合(collection)、數組(array)、函數(function)、對象(object)和工具(utility)五大類。

這里介紹部分的常用方法,詳細請API文檔?http://www.css88.com/doc/underscore/

從API中,你已經可以看出,Underscore沒有任何復雜的結構和流程,它僅僅提供了一系列常用的函數。如果你將API中的方法從頭至尾用一遍,你就會對它非常了解。

盡管如此,但我覺得還是有必要將一些重要的方法拿出來與大家討論,它們十分重要,卻在API中描述地還不夠清楚。

1 Underscore對象封裝

Underscore并沒有在原生的JavaScript對象原型中進行擴展,而是像jQuery一樣,將數據封裝在一個自定義對象中(下文中稱“Underscore對象”)。

你可以通過調用一個Underscore對象的value()方法來獲取原生的JavaScript數據,例如:

javascript 代碼:
  • // 定義一個JavaScript內置對象
  • var jsData = {
  • name : 'data'
  • }
  • ?
  • // 通過_()方法將對象創建為一個Underscore對象
  • // underscoreData對象的原型中包含了Underscore中定義的所有方法,你可以任意使用
  • var underscoreData = _(jsData);
  • ?
  • // 通過value方法獲取原生數據, 即jsData
  • underscoreData.value();
  • 2 優先調用JavaScript 1.6內置方法

    Underscore中有許多方法在JavaScript1.6中已經被納入規范,因此在Underscore對象內部,會優先調用宿主環境提供的內置方法(如果宿主環境已經實現了這些方法),以此提高函數的執行效率。

    而對于不支持JavaScript 1.6的宿主環境,Underscore會通過自己的方式實現,而對開發者來說,這些完全是透明的。

    這里所說的宿主環境,可能是Node.js運行環境,或客戶端瀏覽器。

    3 改變命名空間

    Underscore默認使用_(下劃線)來訪問和創建對象,但這個名字可能不符合我們的命名規范,或容易引起命名沖突。

    我們可以通過noConflict()方法來改變Underscore的命名,并恢復_(下劃線)變量之前的值,例如:

    html 代碼:
  • <script type="text/javascript">
  • var _ = '自定義變量';
  • </script>
  • <script type="text/javascript" src="underscore/underscore-min.js"></script>
  • <script type="text/javascript">
  • // Underscore對象
  • console.dir(_);
  • // 將Underscore對象重命名為us, 后面都通過us來訪問和創建Underscore對象
  • var us = _.noConflict();
  • // 輸出"自定義變量"
  • console.dir(_);
  • </script>
  • 4 鏈式操作

    還記得我們在jQuery中是如何進行鏈接操作嗎?例如:

    javascript 代碼:
  • $('a')
  • .css('position', 'relative')
  • .attr('href', '#')
  • .show();
  • Underscore同樣支持鏈式操作,但你需要先調用chain()方法進行聲明:

    javascript 代碼:
  • var arr = [10, 20, 30];
  • _(arr)
  • .chain()
  • .map(function(item){ return item++; })
  • .first()
  • .value();
  • 如果調用了chain()方法,Underscore會將所調用的方法封裝在一個閉包內,并將返回值封裝為一個Underscore對象并返回:

    javascript 代碼:
  • // 這是Underscore中實現鏈式操作的關鍵函數,它將返回值封裝為一個新的Underscore對象,并再次調用chain()方法,為方法鏈中的下一個函數提供支持。
  • var result = function(obj, chain) {
  • return chain ? _(obj).chain() : obj;
  • }
  • ?

    5 擴展Underscore

    我們可以通過mixin()方法輕松地向Underscore中擴展自定義方法,例如:

    javascript 代碼:
  • _.mixin({
  • method1: function(object) {
  • // todo
  • },
  • method2: function(arr) {
  • // todo
  • },
  • method3: function(fn) {
  • // todo
  • }
  • });
  • 這些方法被追加到Underscore的原型對象中,所有創建的Underscore對象都可以使用這些方法,它們享有和其它方法同樣的環境。

    6 遍歷集合

    each()和map()方法是最常用用到的兩個方法,它們用于迭代一個集合(數組或對象),并依次處理集合中的每一個元素,例如:

    javascript 代碼:
  • var arr = [1, 2, 3];
  • ?
  • _(arr).map(function(item, i) {
  • arr[i] = item + 1;
  • });
  • ?
  • var obj = {
  • first : 1,
  • second : 2
  • }
  • ?
  • _(obj).each(function(value, key) {
  • return obj[key] = value + 1;
  • });
  • map()方法與each()方法的作用、參數相同,但它會將每次迭代函數返回的結果記錄到一個新的數組并返回。

    7 函數節流

    函數節流是指控制一個函數的執行頻率或間隔(就像控制水流的閘門一樣),Underscore提供了debounce()和throttle()兩個方法用于函數節流。

    為了更清楚地描述這兩個方法,假設我們需要實現兩個需求:

      需求1:當用戶在文本框輸入搜索條件時,自動查詢匹配的關鍵字并提示給用戶(就像在Tmall輸入搜索關鍵字時那樣)

    首先分析第1個需求,我們可以綁定文本框的keypress事件,當輸入框內容發生變化時,查詢匹配關鍵字并展示。假設我想查詢“windows phone”,它包含13個字符,而我輸入完成只花了1秒鐘(好像有點快,就意思意思吧),那么在這1秒內,調用了13次查詢方法。這是一件非常恐怖的事情,如果Tmall也這樣實現,我擔心它會不會在光棍節到來之前就掛掉了(當然,它并沒有這么脆弱,但這絕對不是最好的方案)

    更好的方法是,我們希望用戶已經輸入完成,或者正在等待提示(也許他懶得再輸入后面的內容)的時候,再查詢匹配關鍵字。

    最后我們發現,在我們期望的這兩種情況下,用戶會暫時停止輸入,于是我們決定在用戶暫停輸入200毫秒后再進行查詢(如果用戶在不斷地輸入內容,那么我們認為他可能很明確自己想要的關鍵字,所以等一等再提示他)

    這時,利用Underscore中的debounce()函數,我們可以輕松實現這個需求:

    html 代碼:
  • <input type="text" id="search" name="search" />
  • <script type="text/javascript">
  • var query = _(function() {
  • // 在這里進行查詢操作
  • }).debounce(200);
  • ?
  • $('#search').bind('keypress', query);
  • </script>
  • 你能看到,我們的代碼非常簡潔,節流控制在debounce()方法中已經被實現,我們只告訴它當query函數在200毫秒內沒有被調用過的話,就執行我們的查詢操作,然后再將query函數綁定到輸入框的keypress事件。

    query函數是怎么來的?我們在調用debounce()方法時,會傳遞一個執行查詢操作的函數和一個時間(毫秒數),debounce()方法會根據我們傳遞的時間對函數進行節流控制,并返回一個新的函數(即query函數),我們可以放心大膽地調用query函數,而debounce()方法會按要求幫我們做好控制。

      需求2:當用戶拖動瀏覽器滾動條時,調用服務器接口檢查是否有新的內容

    再來分析第2個需求,我們可以將查詢方法綁定到window.onscroll事件,但這顯然不是一個好的做法,因為用戶拖動一次滾動條可能會觸發幾十次甚至上百次onscroll事件。

    我們是否可以使用上面的debounce()方法來進行節流控制?當用戶拖動滾動條完畢后,再查詢新的內容?但這與需求不符,用戶希望在拖動的過程中也能看到新內容的變化。

    因此我們決定這樣做:用戶在拖動時,每兩次查詢的間隔不少于500毫秒,如果用戶拖動了1秒鐘,這可能會觸發200次onscroll事件,但我們最多只進行2次查詢。

    利用Underscore中的throttle()方法,我們也可以輕松實現這個需求:

    html 代碼:
  • <script type="text/javascript">
  • var query = _(function() {
  • // 在這里進行查詢操作
  • }).throttle(500);
  • ?
  • $(window).bind('scroll', query);
  • </script>
  • 代碼仍然十分簡潔,因為在throttle()方法內部,已經為我們實現的所有控制。

    你可能已經發現,debounce()和throttle()兩個方法非常相似(包括調用方式和返回值),作用卻又有不同。

    它們都是用于函數節流,控制函數不被頻繁地調用,節省客戶端及服務器資源。

    • debounce()方法關注函數執行的間隔,即函數兩次的調用時間不能小于指定時間。
    • throttle()方法更關注函數的執行頻率,即在指定頻率內函數只會被調用一次。

    ?

    5.8 模板解析

    Underscore提供了一個輕量級的模板解析函數,它可以幫助我們有效地組織頁面結構和邏輯。

    我將通過一個例子來介紹它:

    html 代碼:
  • <!-- 用于顯示渲染后的標簽 -->
  • <ul id="element"></ul>
  • ?
  • <!-- 定義模板,將模板內容放到一個script標簽中 -->
  • <script type="text/template" id="tpl">
  • <% for(var i = 0; i < list.length; i++) { %>
  • <% var item = list[i] %>
  • <li>
  • <span><%=item.firstName%> <%=item.lastName%></span>
  • <span><%-item.city%></span>
  • </li>
  • <% } %>
  • </script>
  • <script type="text/javascript" src="underscore/underscore-min.js"></script>
  • <script type="text/javascript">
  • // 獲取渲染元素和模板內容
  • var element = $('#element'),
  • tpl = $('#tpl').html();
  • ?
  • // 創建數據, 這些數據可能是你從服務器獲取的
  • var data = {
  • list: [
  • {firstName: '<a href="#">Zhang</a>', lastName: 'San', city: 'Shanghai'},
  • {firstName: 'Li', lastName: 'Si', city: '<a href="#">Beijing</a>'},
  • {firstName: 'Wang', lastName: 'Wu', city: 'Guangzhou'},
  • {firstName: 'Zhao', lastName: 'Liu', city: 'Shenzhen'}
  • ]
  • }
  • ?
  • // 解析模板, 返回解析后的內容
  • var html = _.template(tpl, data);
  • // 將解析后的內容填充到渲染元素
  • element.html(html);
  • </script>
  • 在本例中,我們將模板內容放到一個<script>標簽中,你可能已經注意到標簽的type是text/template而不是text/javascript,因為它無法作為JavaScript腳本直接運行。

    我也建議你將模板內容放在<script>中,因為如果你將它們寫在一個<div>或其它標簽中,它們可能會被添加到DOM樹中進行解析(即使你隱藏了這個標簽也無法避免)。

    ?

    _.template模板函數只能解析3種模板標簽(這比Smarty、JSTL要簡單得多):

    <% ?%>:用于包含JavaScript代碼,這些代碼將在渲染數據時被執行。

    <%= %>:用于輸出數據,可以是一個變量、某個對象的屬性、或函數調用(將輸出函數的返回值)。

    <%- %>:用于輸出數據,同時會將數據中包含的HTML字符轉換為實體形式(例如它會將雙引號轉換為&quot;形式),用于避免XSS攻擊。

    當我們希望將數據中的HTML作為文本顯示出來時,常常會使用<%- %>標簽。

    Underscore還允許你修改這3種標簽的形式,如果我們想使用{% %}、{%= %}、{%- %}作為標簽,可以通過修改templateSettings來實現,就像這樣:

    javascript 代碼:
  • _.templateSettings = {
  • evaluate : /\{%([\s\S]+?)\%\}/g,
  • interpolate : /\{%=([\s\S]+?)\%\}/g,
  • escape : /\{%-([\s\S]+?)%\}/g
  • }
  • 在本例中,我們將模板內容和需要填充的數據傳遞給template方法,它會按以下順序進行處理:

    • 將模板內容解析為可執行的JavaScript(解析模板標簽)
    • 通過with語句將解析后的JavaScript作用域修改為我們傳遞的數據對象,這使我們能夠直接在模板中通過變量形式訪問數據對象的屬性
    • 執行解析后的JavaScript(將數據填充到模板)
    • 返回執行后的結果

    我們經常會遇到一種情況:多次調用template方法將數據渲染到同一個模板。

    假設我們有一個分頁列表,列表中的每一條數據都通過模板渲染,當用戶進入下一頁,我們會獲取下一頁的數據并重新渲染,實際上每次渲染的模板都是同一個,但剛才描述的template所有處理過程總會被執行。

    其實Underscore的template方法提供了一種更高效的調用方式,我們將上面代碼中的最后兩句修改為:

    javascript 代碼:
  • // 解析模板, 返回解析后的內容
  • var render = _.template(tpl);
  • var html = render(data);
  • // 將解析后的內容填充到渲染元素
  • element.html(html);
  • 你會發現細微的差別:我們在調用template方法時只傳遞了模板內容,而沒有傳遞數據,此時template方法會解析模板內容,生成解析后的可執行JavaScript代碼,并返回一個函數,而函數體就是解析后的JavaScript,因此當我們調用該函數渲染數據時,就省去了模板解析的動作。

    你應該將返回的函數存儲起來(就像我將它存儲在render變量中一樣),再通過調用該函數來渲染數據,特別是在同一個模板可能會被多次渲染的情況下,這樣做能提高執行效率(具體提升多少,應該根據你的模板長度和復雜度而定,但無論如何,這都是一個良好的習慣)。

    總結

    以上是生活随笔為你收集整理的Underscore.js常用方法介绍的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 国产精品专区在线观看 | 一区二区三区四区免费 | 好吊视频在线观看 | 亚洲人交配视频 | 国产亚洲精品自拍 | 三级免费黄录像 | 一本一道波多野结衣av黑人 | 黄色私人影院 | 美国式禁忌1980 | 麻豆免费观看网站 | 婷婷色影院 | 欧美三个黑人玩3p | 日本黄色小视频 | 91精品国产自产精品男人的天堂 | 亚洲熟女乱色一区二区三区 | 亚洲成成品网站 | 美女国产一区 | 日本在线一区 | 天天插天天射 | 极品尤物一区二区三区 | 999精品网站 | 天天在线免费视频 | 黄色一级大片在线免费看国产 | 麻豆免费在线 | 午夜精品久久久 | 中文字幕欧美在线 | 黄色av小说在线观看 | 国产一区二区在线播放 | 免费激情 | 白丝美女被草 | 免费黄片毛片 | 欧美中文字幕视频 | 先锋影音av资源站 | 美女张开双腿让男人捅 | 亚洲成a人v欧美综合天堂麻豆 | 免费日韩av| 国产女厕一区二区三区在线视 | 国产亚洲精品久久久久久无几年桃 | 97超碰人人在线 | 姑娘第5集在线观看免费好剧 | 国产又粗又猛又色 | 五月天国产视频 | 中文字幕一区日韩 | 老头糟蹋新婚少妇系列小说 | 偷拍视频久久 | 高h在线观看 | 免费观看黄色一级片 | 国产黑丝在线视频 | 免费观看一级一片 | caoporn免费在线视频 | 思思99re| 国产成人精品在线播放 | 黄色一大片 | 国产东北露脸精品视频 | 末路1997全集免费观看完整版 | 韩国伦理在线视频 | 亚洲av日韩av在线观看 | 18岁免费观看电视连续剧 | 91福利视频网站 | 国产毛片毛片毛片毛片毛片 | 精久久久久久久 | 亚洲第一成人网站 | 欧美成在线观看 | 亚洲第一免费播放区 | 无码国产69精品久久久久网站 | 午夜私人影院 | 97免费观看视频 | 国产日韩成人内射视频 | 99免费在线视频 | 欧美黑人添添高潮a片www | 亚洲妇熟xx妇色黄蜜桃 | 亚洲乱码一区二区三区在线观看 | 性久久久久久久久久 | 美女黄色大片 | 激情片网站 | 日韩精品久久久久久 | 国产色频 | 亚洲精品乱码久久久久久蜜桃欧美 | 校园激情亚洲 | 欧美区在线观看 | 黄色国产小视频 | 奇米av在线 | 亚洲色网址 | 国产精品69久久久久孕妇欧美 | 日本a级片网站 | 欧美女同视频 | 青青青在线视频免费观看 | 国产精品一二三四 | 丝袜天堂 | 欧美成人高清在线 | 日韩一区二区三区免费 | jizz日韩 | 男人用嘴添女人下身免费视频 | 狠狠干2020| 亚洲1234区 | 亚洲av无码一区二区三区人妖 | 国产精品久久毛片av大全日韩 | 国产av剧情一区 | 亚洲一区二区观看播放 |