Underscore並無在原生的JavaScript對象原型中進行擴展,而是像jQuery同樣,將數據封裝在一個自定義對象中(下文稱「Underscore對象」)。生成一個Underscore對象:javascript
<script>html
var jsData = {
name : 'data'
}
// 經過_()方法將對象建立爲一個Underscore對象
var underscoreData = _(jsData); //_就是Underscore構造函數的標識java
// underscoreData對象的原型中包含了Underscore中定義的全部方法,你能夠任意使用
underscoreData.value();ajax
// 經過value方法獲取原生數據, 即jsDatajson
</script>數組
Underscore默認使用_(下劃線)來訪問和建立對象,但這個名字可能不符合咱們的命名規範,或容易引發命名衝突。咱們能夠經過noConflict()方法來改變Underscore的命名,並恢復_(下劃線)變量以前的值,例如:服務器
<script type="text/javascript">
var _ = '自定義變量';
</script>
<script type="text/javascript" src="http://handyxuefeng.blog.163.com/blog/underscore/underscore-min.js"></script>
<script type="text/javascript">
console.log(_); // Underscore對象
var us = _.noConflict(); // 將Underscore對象重命名爲us, 後面都經過us來訪問和建立Underscore對象
console.log(_); // 輸出"自定義變量"
</script>函數
Underscore一樣支持鏈式操做,但你須要先調用chain()方法進行聲明。this
var arr = [10, 20, 30];
_(arr) //新建一個Underscore對象
.chain() //聲明我要鏈式操做了
.map(function(item){ return item++; })
.first()
.value();spa
咱們能夠經過mixin()方法輕鬆地向Underscore中擴展自定義方法,例如:
_.mixin({
method1: function(object) {
// to do
},
method2: function(arr) {
// to do
},
method3: function(fn) {
// to do
}
});
這些方法被追加到Underscore的原型對象中,全部建立的Underscore對象均可以使用這些方法,它們享有和其它方法一樣的環境。
Underscore提供了一個輕量級的模板解析函數,它能夠幫助咱們有效地組織頁面結構和邏輯。handlebars也是作這個處理的。若是是簡單的模板解析,Backbone裏面有自帶的方法,它使用的就是Underscore中的方法。handlebars處理更復雜的模板解析。舉例:
<ul id="element"></ul> //用於顯示渲染後的標籤
<script type="text/template" id="tpl"> //定義模板,將模板內容放到一個script標籤中
<% 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="http://handyxuefeng.blog.163.com/blog/underscore/underscore-min.js"></script>
<script type="text/javascript">
var element = $('#element'),// 獲取渲染元素和模板內容
tpl = $('#tpl').html();
// 建立數據, 這些數據多是你從服務器獲取的
var data = {
list: [
{firstName: '<a href="http://handyxuefeng.blog.163.com/blog/#">Zhang</a>', lastName: 'San', city: 'Shanghai'},
{firstName: 'Li', lastName: 'Si', city: '<a href="http://handyxuefeng.blog.163.com/blog/#">Beijing</a>'},
{firstName: 'Wang', lastName: 'Wu', city: 'Guangzhou'},
{firstName: 'Zhao', lastName: 'Liu', city: 'Shenzhen'}
]
}
// 解析模板, 返回解析後的內容
var html = _.template(tpl, data); //把json數據解析到模板中去,並生成html字符串。
element.html(html); // 將解析後的內容填充到渲染元素
</script>
最後,講幾個underscore中的方法:
map()方法與each()方法的做用、參數相同,但它會將每次迭代函數返回的結果記錄到一個新的數組並返回。
map方法在原生的js中是存在的,each方法是重寫了原生js的forEach方法,請看博客:http://www.cnblogs.com/chaojidan/p/4142338.html
debounce()方法關注函數執行的間隔,即函數兩次的調用時間不能小於指定時間。
throttle()方法更關注函數的執行頻率,即在指定頻率內函數只會被調用一次。
形像的比喻是橡皮球。若是手指按住橡皮球不放,它就一直受力,不能反彈起來,直到鬆手。
debounce 的關注點是空閒的間隔時間。
// ajaxQuery 將在中止輸入 250 毫秒後執行,若是用戶一直輸入(空閒的間隔時間小於250ms),那麼將不會執行ajaxQuery 。
$('#autocomplete').addEventListener('keyup',debounce(250,function() { ajaxQuery(this.value,renderUI); },true))
主要的應用場景:文本輸入keydown 事件,keyup 事件,例如作autocomplete。
形像的比喻是水龍頭或機槍,你能夠控制它的流量或頻率。
throttle 的關注點是連續的執行間隔時間。
// 當窗口大小改變時,以 50 毫秒一次的頻率爲單位執行定位函數 position。由於用戶在拖動窗口時,會觸發無數個resize事件,若是不作節流,它會執行無數次回調方法。所以使用節流方法,使每隔50毫秒(間隔時間),才執行回調方法。
window.addEventListener('resize',throttle(50,position,true) );
主要應用場景:window對象的resize和scroll 事件,mousemove鼠標移動事件
加油!