Underscore.js是一個很精幹的庫,壓縮後只有4KB。它提供了幾十種函數式編程的方法,彌補了標準庫的不足,大大方便了JavaScript的編程。MVC框架Backbone.js就將這個庫做爲本身的工具庫。除了能夠在瀏覽器環境使用,Underscore.js還能夠用於Node.js。javascript
Underscore.js定義了一個下劃線(_)對象,函數庫的全部方法都屬於這個對象。這些方法大體上能夠分紅:集合(collection)、數組(array)、函數(function)、對象(object)和工具(utility)五大類。css
nderscore is a JavaScript library that provides a whole mess of 一大堆useful functional programming helpers without extending any built-in objects. It’s the answer to the question: 「If I sit down in front of a blank HTML page, and want to start being productive immediately, what do I need?」 … and the tie to go along with jQuery's tux andBackbone's suspenders.java
Underscore provides 80-odd 80左右functions that support both the usual functional suspects:map, select, invoke — as well as more specialized helpers: function binding, javascript templating, deep equality testing, and so on. It delegates to built-in functions, if present, so modern browsers will use the native implementations of forEach, map,reduce, filter, every, some and indexOf.jquery
A complete Test & Benchmark Suite is included for your perusal.git
Underscore提供的60多個函數:github
http://www.css88.com/doc/underscore/編程
部分函數:數組
Collections(集合)
each, map, reduce, reduceRight, find, filter, reject, all, any, include, invoke,pluck, max, min, sortBy, groupBy, sortedIndex, shuffle, toArray, size瀏覽器
Arrays(數組)
first, initial, last, rest, compact, flatten, without, union, intersection,difference, uniq, zip, indexOf, lastIndexOf, rangeapp
Functions(函數)
bind, bindAll, memoize, delay, defer, throttle, debounce, once, after, wrap,compose
Objects(對象)
keys, values, functions, extend, defaults, clone, tap, isEqual, isEmpty,isElement, isArray, isArguments, isFunction, isString, isNumber, isBoolean,isDate, isRegExp, isNaN, isNull, isUndefined
Utility(功能)
noConflict, identity, times, mixin, uniqueId, escape, template
英文:
中文翻譯:http://www.css88.com/doc/underscore/
each_.each(list, iterator, [context])
Alias: forEach
Iterates over a list of elements, yielding each in turn to an iterator function. Theiterator is bound to the context object, if one is passed. Each invocation of iterator is called with three arguments: (element, index, list). If list is a JavaScript object,iterator's arguments will be (value, key, list). Delegates to the native forEachfunction if it exists, and returns the original list for chaining.
_.each([1, 2, 3], alert); => alerts each number in turn... _.each({one: 1, two: 2, three: 3}, alert); => alerts each number value in turn...
Note: Collection functions work on arrays, objects, and array-like objects such asarguments, NodeList and similar. But it works by duck-typing, so avoid passing objects with a numeric length property. It's also good to note that an each loop cannot be broken out of — to break, use _.find instead.
map_.map(list, iterator, [context])
Alias: collect
經過變換函數(iterator迭代器)把list中的每一個值映射到一個新的數組中(愚人碼頭注:產生一個新的數組)。若是存在原生的map方法,就用原生map方法來代替。若是list是個JavaScript對象,iterator的參數是(value, key, list)。
_.map([1, 2, 3], function(num){ return num * 3; }); => [3, 6, 9] _.map({one: 1, two: 2, three: 3}, function(num, key){ return num * 3; }); => [3, 6, 9]
reduce_.reduce(list, iterator, memo, [context])
Aliases: inject, foldl
別名爲 inject 和 foldl, reduce方法把list中元素歸結爲一個單獨的數值。Memo是reduce函數的初始值,reduce的每一步都須要由iterator返回。這個迭代傳遞4個參數:memo, value 和 迭代的index(或者 key)和最後一個引用的整個 list。
var sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0); => 6
reduceRight_.reduceRight(list, iterator, memo, [context])
Alias: foldr
reducRight是從右側開始組合的元素的reduce函數,若是存在JavaScript 1.8版本的reduceRight,則用其代替。Foldr在javascript中不像其它有懶計算的語言那麼有用(lazy evaluation:一種求值策略,只有當表達式的值真正須要時纔對表達式進行計算)。
var list = [[0, 1], [2, 3], [4, 5]]; var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); => [4, 5, 2, 3, 0, 1]
find_.find(list, iterator, [context])
Alias: detect
遍歷list,返回第一個經過iterator迭代器真值檢測的元素值,若是沒有值傳遞給測試迭代器將返回undefined
。 若是找到匹配的元素,函數將當即返回,不會遍歷整個list。
var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); => 2
filter_.filter(list, iterator, [context])
Alias: select
遍歷list中的每一個值,返回包含全部經過iterator真值檢測的元素值。若是存在原生filter方法,則用原生的filter方法。
var evens = _.filter([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); => [2, 4, 6]
where_.where(list, properties)
遍歷list中的每個值,返回一個數組,這個數組包含包含properties所列出的屬性的全部的鍵 - 值對。
_.where(listOfPlays, {author: "Shakespeare", year: 1611}); => [{title: "Cymbeline", author: "Shakespeare", year: 1611}, {title: "The Tempest", author: "Shakespeare", year: 1611}]
findWhere_.findWhere(list, properties)
遍歷list中的每個值,返回匹配properties所列出的屬性的全部的鍵 - 值對的第一個值。
若是沒有找到匹配的屬性,或者list是空的,那麼將返回undefined。
_.findWhere(publicServicePulitzers, {newsroom: "The New York Times"}); => {year: 1918, newsroom: "The New York Times", reason: "For its public service in publishing in full so many official reports, documents and speeches by European statesmen relating to the progress and conduct of the war."}
reject_.reject(list, iterator, [context])
返回list中沒有經過iterator真值檢測的元素集合,與filter相反。
var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); => [1, 3, 5]
toArray方法將對象轉爲數組,只包含對象成員的值。典型應用是將對相似數組的對象轉爲真正的數組。
_.toArray({a:0,b:1,c:2});
// [0, 1, 2]
pluck方法將多個對象的某一個屬性的值,提取成一個數組。
var stooges = [{name : 'moe', age : 40}, {name : 'larry', age : 50}, {name : 'curly', age : 60}];
_.pluck(stooges, 'name');
// ["moe", "larry", "curly"]
在不一樣的運行環境下,JavaScript函數內部的變量所在的上下文是不一樣的。這種特性會給程序帶來不肯定性,爲了解決這個問題,Underscore.js提供了兩個方法,用來給函數綁定上下文。
(1)bind方法
該方法綁定函數運行時的上下文,返回一個新函數。
bind_.bind(function, object, *arguments)
Bind a function to an object, meaning that whenever the function is called, the value of this will be the object. Optionally, pass arguments to the function to pre-fill them, also known as partial application.
var func = function(greeting){ return greeting + ': ' + this.name };
func = _.bind(func, {name: 'moe'}, 'hi');
func();
=> 'hi: moe'
bindAll_.bindAll(object, *methodNames)
Binds a number of methods on the object, specified by methodNames, to be run in the context of that object whenever they are invoked. Very handy for binding functions that are going to be used as event handlers, which would otherwise be invoked with a fairly useless this. methodNames are required.
var buttonView = {
label : 'underscore',
onClick: function(){ alert('clicked: ' + this.label); },
onHover: function(){ console.log('hovering: ' + this.label); }
};
_.bindAll(buttonView, 'onClick', 'onHover');
// When the button is clicked, this.label will have the correct value.
jQuery('#underscore_button').bind('click', buttonView.onClick);
var o = {
p: 2,
m: function (){console.log(this.p);}
};
o.m()
// 2
_.bind(o.m,{p:1})()
// 1
上面代碼將o.m方法綁定到一個新的對象上面。
除了前兩個參數之外,bind方法還能夠接受更多參數,它們表示函數方法運行時所需的參數。
var add = function(n1,n2,n3) {
console.log(this.sum + n1 + n2 + n3);
};
_.bind(add, {sum:1}, 1, 1, 1)()
// 4
上面代碼中bind方法有5個參數,最後那三個是給定add方法的運行參數,因此運行結果爲4。
2)bindall方法
該方法能夠一次將多個方法,綁定在某個對象上面。
var o = {
p1 : '123',
p2 : '456',
m1 : function() { console.log(this.p1); },
m2 : function() { console.log(this.p2); },
};
_.bindAll(o, 'm1', 'm2');
上面代碼一次性將兩個方法(m1和m2)綁定在o對象上面。
(3)partial方法
除了綁定上下文,Underscore.js還容許綁定參數。partial方法將函數與某個參數綁定,而後做爲一個新函數返回。
var add = function(a, b) { return a + b; };
add5 = _.partial(add, 5);
add5(10);
// 15
(4)wrap方法
該方法將一個函數做爲參數,傳入另外一個函數,最終返回前者的一個新版本。
var hello = function(name) { return "hello: " + name; };
hello = _.wrap(hello, function(func) {
return "before, " + func("moe") + ", after";
});
hello();
// 'before, hello: moe, after'
上面代碼先定義hello函數,而後將hello傳入一個匿名定義,返回一個新版本的hello函數。
(5)compose方法
該方法接受一系列函數做爲參數,由後向前依次運行,上一個函數的運行結果,做爲後一個函數的運行參數。也就是說,將f(g(),h())的形式轉化爲f(g(h()))。
var greet = function(name){ return "hi: " + name; };
var exclaim = function(statement){ return statement + "!"; };
var welcome = _.compose(exclaim, greet);
welcome('moe');
// 'hi: moe!'
上面代碼調用welcome時,先運行greet函數,再運行exclaim函數。而且,greet函數的運行結果是exclaim函數運行時的參數。