中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久

深入解析Backbone.js框架的依賴庫Underscore.js的作用
來源:易賢網 閱讀:1073 次 日期:2016-07-02 13:13:06
溫馨提示:易賢網小編為您整理了“深入解析Backbone.js框架的依賴庫Underscore.js的作用”,方便廣大網友查閱!

這篇文章主要介紹了深入解析Backbone.js框架的依賴庫Underscore.js的作用,用過Node.js的朋友對Underscore一定不會陌生:)需要的朋友可以參考下

backbone必須依賴underscore.js才能夠使用,它必須通過underscore中的函數來完成訪問頁面元素、處理元素的基本操作。

注:backbone可以很好的與其它js庫一起工作,所以說它是一個庫,而不是框架。

Underscore并沒有對原生對象進行擴展,而是調用_()方法進行封裝,一旦封裝完成,js對象就變為Underscore對象,也可以通過Underscore對象的Value()方法獲取原生js對象中的數據。(jquery通過$()方法得到Jquery對象)

Underscore總共有60多個函數,按照處理對象的不同,可以分為集合類、數組類、功能函數類、對象類、工具函數類五大類模塊。

underscore template()函數說明:

該函數包含三種模板:

(1)<% %>:包含邏輯代碼,渲染后不會展現。

(2)<%= %>:數據類型,渲染后展示數據。

(3)<%- %>:將HTML標記轉換為常用字符串,以避免代碼攻擊。

調用格式:

_.template(templateString, [data], [setting])

沒有實現雙向數據綁定。

1、Underscore對象封裝

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

你可以通過調用一個Underscore對象的value()方法來獲取原生的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的命名,并恢復_(下劃線)變量之前的值,例如:

<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中是如何進行鏈接操作嗎?例如:

$('a') 

 .css('position', 'relative') 

 .attr('href', '#') 

 .show(); 

Underscore同樣支持鏈式操作,但你需要先調用chain()方法進行聲明:

var arr = [10, 20, 30]; 

_(arr) 

 .chain() 

 .map(function(item){ return item++; }) 

 .first() 

 .value(); 

如果調用了chain()方法,Underscore會將所調用的方法封裝在一個閉包內,并將返回值封裝為一個Underscore對象并返回:

// 這是Underscore中實現鏈式操作的關鍵函數,它將返回值封裝為一個新的Underscore對象,并再次調用chain()方法,為方法鏈中的下一個函數提供支持。 

var result = function(obj, chain) { 

 return chain ? _(obj).chain() : obj; 

5、擴展Underscore

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

_.mixin({ 

 method1: function(object) { 

 // todo 

 }, 

 method2: function(arr) { 

 // todo 

 }, 

 method3: function(fn) { 

 // todo 

 } 

}); 

這些方法被追加到Underscore的原型對象中,所有創建的Underscore對象都可以使用這些方法,它們享有和其它方法同樣的環境。

6、遍歷集合

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

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()函數,我們可以輕松實現這個需求:

<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()方法,我們也可以輕松實現這個需求:

<script type="text/javascript"> 

 var query = _(function() { 

 // 在這里進行查詢操作 

 }).throttle(500); 

 $(window).bind('scroll', query); 

</script> 

代碼仍然十分簡潔,因為在throttle()方法內部,已經為我們實現的所有控制。

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

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

 debounce()方法關注函數執行的間隔,即函數兩次的調用時間不能小于指定時間。

throttle()方法更關注函數的執行頻率,即在指定頻率內函數只會被調用一次。

 8、模板解析

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

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

<!-- 用于顯示渲染后的標簽 --> 

<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字符轉換為實體形式(例如它會將雙引號轉換為"形式),用于避免XSS攻擊。

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

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

_.templateSettings = { 

 evaluate : /\{%([\s\S]+?)\%\}/g, 

 interpolate : /\{%=([\s\S]+?)\%\}/g, 

 escape : /\{%-([\s\S]+?)%\}/g 

 在本例中,我們將模板內容和需要填充的數據傳遞給template方法,它會按以下順序進行處理:

(1)將模板內容解析為可執行的JavaScript(解析模板標簽)

(2)通過with語句將解析后的JavaScript作用域修改為我們傳遞的數據對象,這使我們能夠直接在模板中通過變量形式訪問數據對象的屬性

(3)執行解析后的JavaScript(將數據填充到模板)

(4)返回執行后的結果

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

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

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

// 解析模板, 返回解析后的內容 

var render = _.template(tpl); 

var html = render(data); 

// 將解析后的內容填充到渲染元素 

element.html(html); 

你會發現細微的差別:我們在調用template方法時只傳遞了模板內容,而沒有傳遞數據,此時template方法會解析模板內容,生成解析后的可執行JavaScript代碼,并返回一個函數,而函數體就是解析后的JavaScript,因此當我們調用該函數渲染數據時,就省去了模板解析的動作。

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

更多信息請查看網絡編程
由于各方面情況的不斷調整與變化,易賢網提供的所有考試信息和咨詢回復僅供參考,敬請考生以權威部門公布的正式信息和咨詢為準!

2026上岸·考公考編培訓報班

  • 報班類型
  • 姓名
  • 手機號
  • 驗證碼
關于我們 | 聯系我們 | 人才招聘 | 網站聲明 | 網站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
工業和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網安備53010202001879號 人力資源服務許可證:(云)人服證字(2023)第0102001523號
云南網警備案專用圖標
聯系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關注公眾號:hfpxwx
咨詢QQ:1093837350(9:00—18:00)版權所有:易賢網
云南網警報警專用圖標
中文字幕免费精品_亚洲视频自拍_亚洲综合国产激情另类一区_色综合咪咪久久
免费人成精品欧美精品| 老司机成人网| 亚洲精品欧美日韩专区| 日韩午夜在线播放| 亚洲欧美偷拍卡通变态| 久久综合色天天久久综合图片| 免费久久精品视频| 国产精品成人av性教育| 国产一区二区三区精品欧美日韩一区二区三区 | 精品51国产黑色丝袜高跟鞋| 亚洲精品一区二区三区99| 性久久久久久久久| 欧美激情自拍| 韩国福利一区| 亚洲男女自偷自拍图片另类| 欧美成人黄色小视频| 国产欧美韩国高清| 夜夜爽99久久国产综合精品女不卡| 欧美一级理论片| 欧美日韩黄色一区二区| 一区二区自拍| 欧美中文字幕在线| 国产精品久久久久影院色老大| 在线成人激情| 久久精品成人一区二区三区| 欧美亚一区二区| 亚洲麻豆视频| 蜜臀a∨国产成人精品| 国产亚洲精品aa午夜观看| 亚洲午夜女主播在线直播| 欧美黄污视频| 亚洲国产精品久久久久秋霞不卡 | 免费的成人av| 国产一区二区日韩| 午夜国产一区| 国产精品每日更新| 亚洲与欧洲av电影| 国产精品福利在线观看| 夜夜嗨一区二区| 欧美日韩亚洲一区二区三区在线观看| 在线看日韩av| 久久女同互慰一区二区三区| 国产一级久久| 久久久久久久波多野高潮日日| 国产在线拍偷自揄拍精品| 欧美一区二区三区视频免费| 国产欧亚日韩视频| 久久福利精品| 一区二区自拍| 欧美99在线视频观看| 亚洲国产美国国产综合一区二区| 久久综合网hezyo| 亚洲高清精品中出| 欧美国产日韩免费| 99精品视频一区| 欧美视频在线观看一区| 亚洲性图久久| 国产欧美精品一区二区三区介绍| 亚洲欧美国产精品桃花| 国产免费成人| 久久久综合网站| 亚洲国产导航| 欧美日韩亚洲视频一区| 亚洲一级在线观看| 国产人成精品一区二区三| 久久精品女人| 136国产福利精品导航网址| 米奇777超碰欧美日韩亚洲| 亚洲精品极品| 国产精品私房写真福利视频| 久久精品国产亚洲高清剧情介绍 | 国产亚洲福利一区| 久久亚洲一区二区三区四区| 亚洲区一区二| 国产精品日本精品| 久久久视频精品| 最新中文字幕亚洲| 欧美午夜一区二区三区免费大片 | 中文亚洲欧美| 国产一区二区三区四区hd| 久久婷婷国产综合精品青草| 最新精品在线| 国产精品一区二区久久国产| 久久人人爽人人爽| 夜夜爽夜夜爽精品视频| 国产欧美一区二区视频| 欧美成人午夜剧场免费观看| 亚洲欧美另类在线观看| 91久久夜色精品国产九色| 欧美午夜免费影院| 美女性感视频久久久| 亚洲午夜电影| 亚洲福利视频一区| 国产精品私拍pans大尺度在线| 鲁大师影院一区二区三区| 亚洲一区在线视频| 亚洲国产一二三| 国产午夜精品一区理论片飘花 | 久久久在线视频| 亚洲无线视频| 亚洲国产综合91精品麻豆| 国产欧美日韩视频| 欧美啪啪成人vr| 久久综合九色欧美综合狠狠| 亚洲欧美国产高清va在线播| 亚洲国产天堂久久国产91| 国产一区二区视频在线观看| 欧美视频在线观看 亚洲欧| 美女精品在线| 久久久久久久久久看片| 亚洲欧美日韩中文在线制服| 日韩一级黄色片| 亚洲欧洲一区二区三区久久| 精品成人在线视频| 国产欧亚日韩视频| 国产精品成人播放| 欧美日韩免费观看一区二区三区| 久久夜色精品国产欧美乱极品| 午夜精品久久久久久久久久久久 | 久久精品国产免费| 亚洲欧美bt| 中国亚洲黄色| 99精品黄色片免费大全| 在线精品福利| 一区二区三区在线观看欧美| 国产视频一区在线观看一区免费| 欧美日韩一区二区三区四区在线观看 | 欧美日韩国产页| 欧美成人黄色小视频| 久久国产精品久久久久久久久久| 亚洲欧美日韩精品久久亚洲区| 一区二区三区日韩欧美精品| 亚洲人成在线免费观看| 亚洲人体1000| 亚洲理论在线观看| 亚洲精品乱码久久久久久久久 | 久久综合影音| 久久亚洲不卡| 久久综合给合久久狠狠狠97色69| 久久精品一区二区三区不卡| 久久国产视频网| 久久人体大胆视频| 美日韩精品视频| 欧美成人精品不卡视频在线观看 | 亚洲午夜电影在线观看| 一本色道久久综合亚洲精品高清 | 久久久久国产精品一区三寸| 欧美一区二区视频观看视频| 欧美一二三视频| 欧美在线视频日韩| 久久九九国产| 每日更新成人在线视频| 麻豆成人av| 欧美日韩免费在线| 欧美午夜视频在线观看| 国产区亚洲区欧美区| 韩国av一区二区三区| 亚洲国产精品福利| 一区二区三区高清在线| 亚洲自拍三区| 久久精品天堂| 欧美成人精品高清在线播放| 欧美日韩精品不卡| 国产乱码精品一区二区三区av | 午夜精品一区二区三区在线视| 亚洲免费影院| 久久精品免费电影| 欧美激情小视频| 国产精品日韩在线| 伊人久久婷婷色综合98网| 99国内精品| 午夜亚洲福利| 欧美凹凸一区二区三区视频| 国产精品草莓在线免费观看| 激情偷拍久久| 正在播放欧美一区| 久久久久五月天| 欧美日韩国产小视频| 国产欧美日韩精品在线| 91久久久久久久久| 亚洲欧美激情视频| 欧美国产另类| 国产亚洲一区在线| 99精品国产一区二区青青牛奶| 欧美在线免费| 欧美日韩一级黄| 在线精品亚洲| 性18欧美另类| 欧美日韩国产综合新一区| 国产小视频国产精品| 日韩视频在线一区| 久久人人爽爽爽人久久久| 欧美天堂亚洲电影院在线观看 | 国产日韩精品久久| 亚洲精品国产系列| 久久精品一区二区三区不卡牛牛 | 欧美精品日韩一区| 国产日韩欧美亚洲| 一区二区三区高清在线| 另类亚洲自拍|