茄子在线看片免费人成视频,午夜福利精品a在线观看,国产高清自产拍在线观看,久久综合久久狠狠综合

    <s id="ddbnn"></s>
  • <sub id="ddbnn"><ol id="ddbnn"></ol></sub>

  • <legend id="ddbnn"></legend><s id="ddbnn"></s>

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

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

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

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

    Underscore并沒有對原生對象進行擴展,而是調(diào)用_()方法進行封裝,一旦封裝完成,js對象就變?yōu)閁nderscore對象,也可以通過Underscore對象的Value()方法獲取原生js對象中的數(shù)據(jù)。(jquery通過$()方法得到Jquery對象)

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

    underscore template()函數(shù)說明:

    該函數(shù)包含三種模板:

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

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

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

    調(diào)用格式:

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

    沒有實現(xiàn)雙向數(shù)據(jù)綁定。

    1、Underscore對象封裝

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

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

    // 定義一個JavaScript內(nèi)置對象 

    var jsData = { 

     name : 'data'

    // 通過_()方法將對象創(chuàng)建為一個Underscore對象 

    // underscoreData對象的原型中包含了Underscore中定義的所有方法,你可以任意使用 

    var underscoreData = _(jsData); 

    // 通過value方法獲取原生數(shù)據(jù), 即jsData 

    underscoreData.value();

     2、優(yōu)先調(diào)用JavaScript 1.6內(nèi)置方法

    Underscore中有許多方法在JavaScript1.6中已經(jīng)被納入規(guī)范,因此在Underscore對象內(nèi)部,會優(yōu)先調(diào)用宿主環(huán)境提供的內(nèi)置方法(如果宿主環(huán)境已經(jīng)實現(xiàn)了這些方法),以此提高函數(shù)的執(zhí)行效率。

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

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

    3、改變命名空間

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

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

    <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來訪問和創(chuàng)建Underscore對象 

     var us = _.noConflict(); 

     // 輸出"自定義變量" 

     console.dir(_); 

    </script> 

    4、鏈式操作

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

    $('a') 

     .css('position', 'relative') 

     .attr('href', '#') 

     .show(); 

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

    var arr = [10, 20, 30]; 

    _(arr) 

     .chain() 

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

     .first() 

     .value(); 

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

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

    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的原型對象中,所有創(chuàng)建的Underscore對象都可以使用這些方法,它們享有和其它方法同樣的環(huán)境。

    6、遍歷集合

    each()和map()方法是最常用用到的兩個方法,它們用于迭代一個集合(數(shù)組或?qū)ο螅⒁来翁幚砑现械拿恳粋€元素,例如:

    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()方法的作用、參數(shù)相同,但它會將每次迭代函數(shù)返回的結(jié)果記錄到一個新的數(shù)組并返回。

    7、函數(shù)節(jié)流

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

    為了更清楚地描述這兩個方法,假設(shè)我們需要實現(xiàn)兩個需求:

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

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

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

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

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

    <input type="text" id="search" name="search" /> 

    <script type="text/javascript"> 

     var query = _(function() { 

     // 在這里進行查詢操作 

     }).debounce(200); 

     $('#search').bind('keypress', query); 

    </script> 

    你能看到,我們的代碼非常簡潔,節(jié)流控制在debounce()方法中已經(jīng)被實現(xiàn),我們只告訴它當query函數(shù)在200毫秒內(nèi)沒有被調(diào)用過的話,就執(zhí)行我們的查詢操作,然后再將query函數(shù)綁定到輸入框的keypress事件。

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

    需求2:當用戶拖動瀏覽器滾動條時,調(diào)用服務(wù)器接口檢查是否有新的內(nèi)容

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

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

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

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

    <script type="text/javascript"> 

     var query = _(function() { 

     // 在這里進行查詢操作 

     }).throttle(500); 

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

    </script> 

    代碼仍然十分簡潔,因為在throttle()方法內(nèi)部,已經(jīng)為我們實現(xiàn)的所有控制。

    你可能已經(jīng)發(fā)現(xiàn),debounce()和throttle()兩個方法非常相似(包括調(diào)用方式和返回值),作用卻又有不同。

    它們都是用于函數(shù)節(jié)流,控制函數(shù)不被頻繁地調(diào)用,節(jié)省客戶端及服務(wù)器資源。

     debounce()方法關(guān)注函數(shù)執(zhí)行的間隔,即函數(shù)兩次的調(diào)用時間不能小于指定時間。

    throttle()方法更關(guān)注函數(shù)的執(zhí)行頻率,即在指定頻率內(nèi)函數(shù)只會被調(diào)用一次。

     8、模板解析

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

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

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

    <ul id="element"></ul> 

    <!-- 定義模板,將模板內(nèi)容放到一個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"> 

     // 獲取渲染元素和模板內(nèi)容 

     var element = $('#element'), 

     tpl = $('#tpl').html(); 

     // 創(chuàng)建數(shù)據(jù), 這些數(shù)據(jù)可能是你從服務(wù)器獲取的 

     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'} 

     ] 

     } 

     // 解析模板, 返回解析后的內(nèi)容 

     var html = _.template(tpl, data); 

     // 將解析后的內(nèi)容填充到渲染元素 

     element.html(html); 

    </script> 

    在本例中,我們將模板內(nèi)容放到一個<script>標簽中,你可能已經(jīng)注意到標簽的type是text/template而不是text/javascript,因為它無法作為JavaScript腳本直接運行。

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

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

    <%  %>:用于包含JavaScript代碼,這些代碼將在渲染數(shù)據(jù)時被執(zhí)行。

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

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

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

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

    _.templateSettings = { 

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

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

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

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

    (1)將模板內(nèi)容解析為可執(zhí)行的JavaScript(解析模板標簽)

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

    (3)執(zhí)行解析后的JavaScript(將數(shù)據(jù)填充到模板)

    (4)返回執(zhí)行后的結(jié)果

    我們經(jīng)常會遇到一種情況:多次調(diào)用template方法將數(shù)據(jù)渲染到同一個模板。

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

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

    // 解析模板, 返回解析后的內(nèi)容 

    var render = _.template(tpl); 

    var html = render(data); 

    // 將解析后的內(nèi)容填充到渲染元素 

    element.html(html); 

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

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

    更多信息請查看網(wǎng)絡(luò)編程
    易賢網(wǎng)手機網(wǎng)站地址:深入解析Backbone.js框架的依賴庫Underscore.js的作用

    2026上岸·考公考編培訓(xùn)報班

    • 報班類型
    • 姓名
    • 手機號
    • 驗證碼
    關(guān)于我們 | 聯(lián)系我們 | 人才招聘 | 網(wǎng)站聲明 | 網(wǎng)站幫助 | 非正式的簡要咨詢 | 簡要咨詢須知 | 新媒體/短視頻平臺 | 手機站點 | 投訴建議
    工業(yè)和信息化部備案號:滇ICP備2023014141號-1 云南省教育廳備案號:云教ICP備0901021 滇公網(wǎng)安備53010202001879號 人力資源服務(wù)許可證:(云)人服證字(2023)第0102001523號
    聯(lián)系電話:0871-65099533/13759567129 獲取招聘考試信息及咨詢關(guān)注公眾號:hfpxwx
    咨詢QQ:1093837350(9:00—18:00)版權(quán)所有:易賢網(wǎng)