javascript轮子(JavaScript实用库)——underscore笔记(一)
当遇到某些小型项目没有jquery可用时寸步难行,主要是因为jquery庞大不愿意用,其次是jquery主攻DOM解析,很多字符串数组对象还得自己实现。最近,发现了一个超级厉害的轮子——underscore,从这个javascript框架上我看到了PHP的影子,实现了大量字符串和数组的函数。
首先,贴一下开源仓库地址:https://github.com/jashkenas/underscore
underscore提供了一整套函数式编程的实用功能,但是没有扩展任何JavaScript内置对象。它是这个问题的答案:“如果我在一个空白的HTML页面前坐下, 并希望立即开始工作, 我需要什么?”
Underscore提供了100多个函数,包括常用的: map, filter, invoke — 当然还有更多专业的辅助函数,如:函数绑定, JavaScript模板功能,创建快速索引, 强类型相等测试, 等等.
安装(Installation)
Node.js npm install underscore Meteor.js meteor add underscore Require.js require(["underscore"], ... Bower bower install underscore Component component install jashkenas/underscore
更多的情况下,我们只是在html中引入这个框架,和jquery一样的使用方式,使用_代替$即可。
<script src="underscore.js" type="text/javascript"></script>
集合函数 (数组 或对象)
each_.each(list, iteratee, [context])
Alias: forEach
遍历list中的所有元素,按顺序用遍历输出每个元素。如果传递了context参数,则把iteratee绑定到context对象上。每次调用iteratee都会传递三个参数:(element, index, list)。如果list是个JavaScript对象,iteratee的参数是(value, key, list))。返回list以方便链式调用。(愚人码头注:如果存在原生的forEach方法,Underscore就使用它代替。)
_.each([1, 2, 3], alert); => alerts each number in turn... _.each({one: 1, two: 2, three: 3}, alert); => alerts each number value in turn...
注意:集合函数能在数组,对象,和类数组对象,比如arguments, NodeList和类似的数据类型上正常工作。 但是它通过鸭子类型工作,所以要避免传递一个不固定length属性的对象(愚人码头注:对象或数组的长度(length)属性要固定的)。每个循环不能被破坏 - 打破, 使用_.find代替,这也是很好的注意。
map_.map(list, iteratee, [context])
Alias: collect
通过转换函数(iteratee迭代器)映射列表中的每个值产生价值的新数组。iteratee传递三个参数:value,然后是迭代 index(或 key 愚人码头注:如果list是个JavaScript对象是,这个参数就是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] _.map([[1, 2], [3, 4]], _.first); => [1, 3]
reduce_.reduce(list, iteratee, [memo], [context])
Aliases: inject, foldl
别名为 inject 和 foldl, reduce方法把list中元素归结为一个单独的数值。Memo是reduce函数的初始值,reduce的每一步都需要由iteratee返回。这个迭代传递4个参数:memo,value 和 迭代的index(或者 key)和最后一个引用的整个 list。
如果没有memo传递给reduce的初始调用,iteratee不会被列表中的第一个元素调用。第一个元素将取代 传递给列表中下一个元素调用iteratee的memo参数。
var sum = _.reduce([1, 2, 3], function(memo, num){ return memo + num; }, 0); => 6
reduceRight_.reduceRight(list, iteratee, 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, predicate, [context])
Alias: detect
在list中逐项查找,返回第一个通过predicate迭代函数真值检测的元素值,如果没有值传递给测试迭代器将返回undefined
。 如果找到匹配的元素,函数将立即返回,不会遍历整个list。
var even = _.find([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); => 2
filter_.filter(list, predicate, [context])
Alias: select
遍历list中的每个值,返回包含所有通过predicate真值检测的元素值。(愚人码头注:如果存在原生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, predicate, [context])
返回list中没有通过predicate真值检测的元素集合,与filter相反。
var odds = _.reject([1, 2, 3, 4, 5, 6], function(num){ return num % 2 == 0; }); => [1, 3, 5]
every_.every(list, [predicate], [context])
Alias: all
如果list中的所有元素都通过predicate的真值检测就返回true。(愚人码头注:如果存在原生的every方法,就使用原生的every。)
_.every([true, 1, null, 'yes'], _.identity); => false
some_.some(list, [predicate], [context])
Alias: any
如果list中有任何一个元素通过 predicate 的真值检测就返回true。一旦找到了符合条件的元素, 就直接中断对list的遍历. (愚人码头注:如果存在原生的some方法,就使用原生的some。)
_.some([null, 0, 'yes', false]); => true
contains_.contains(list, value, [fromIndex])
Alias: includes
如果list包含指定的value则返回true(愚人码头注:使用===检测)。如果list 是数组,内部使用indexOf判断。使用fromIndex来给定开始检索的索引位置。
_.contains([1, 2, 3], 3); => true
invoke_.invoke(list, methodName, *arguments)
在list的每个元素上执行methodName方法。 任何传递给invoke的额外参数,invoke都会在调用methodName方法的时候传递给它。
_.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); => [[1, 5, 7], [1, 2, 3]]
pluck_.pluck(list, propertyName)
pluck也许是map最常使用的用例模型的简化版本,即萃取数组对象中某属性值,返回一个数组。
var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}]; _.pluck(stooges, 'name'); => ["moe", "larry", "curly"]
max_.max(list, [iteratee], [context])
返回list中的最大值。如果传递iteratee参数,iteratee将作为list中每个值的排序依据。如果list为空,将返回-Infinity,所以你可能需要事先用isEmpty检查 list 。
var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}]; _.max(stooges, function(stooge){ return stooge.age; }); => {name: 'curly', age: 60};
min_.min(list, [iteratee], [context])
返回list中的最小值。如果传递iteratee参数,iteratee将作为list中每个值的排序依据。如果list为空,将返回-Infinity,所以你可能需要事先用isEmpty检查 list 。
var numbers = [10, 5, 100, 2, 1000]; _.min(numbers); => 2
sortBy_.sortBy(list, iteratee, [context])
返回一个排序后的list拷贝副本。如果传递iteratee参数,iteratee将作为list中每个值的排序依据。迭代器也可以是字符串的属性的名称进行排序的(比如 length)。
_.sortBy([1, 2, 3, 4, 5, 6], function(num){ return Math.sin(num); }); => [5, 4, 6, 3, 1, 2] var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}]; _.sortBy(stooges, 'name'); => [{name: 'curly', age: 60}, {name: 'larry', age: 50}, {name: 'moe', age: 40}];
groupBy_.groupBy(list, iteratee, [context])
把一个集合分组为多个集合,通过 iterator 返回的结果进行分组. 如果 iterator 是一个字符串而不是函数, 那么将使用iterator 作为各元素的属性名来对比进行分组.
_.groupBy([1.3, 2.1, 2.4], function(num){ return Math.floor(num); }); => {1: [1.3], 2: [2.1, 2.4]} _.groupBy(['one', 'two', 'three'], 'length'); => {3: ["one", "two"], 5: ["three"]}
indexBy_.indexBy(list, iteratee, [context])
给定一个list,和 一个用来返回一个在列表中的每个元素键 的iterator 函数(或属性名), 返回一个每一项索引的对象。和groupBy非常像,但是当你知道你的键是唯一的时候可以使用indexBy 。
var stooges = [{name: 'moe', age: 40}, {name: 'larry', age: 50}, {name: 'curly', age: 60}]; _.indexBy(stooges, 'age'); => { "40": {name: 'moe', age: 40}, "50": {name: 'larry', age: 50}, "60": {name: 'curly', age: 60} }
countBy_.countBy(list, iteratee, [context])
排序一个列表组成一个组,并且返回各组中的对象的数量的计数。类似groupBy,但是不是返回列表的值,而是返回在该组中值的数目。
_.countBy([1, 2, 3, 4, 5], function(num) { return num % 2 == 0 ? 'even': 'odd'; }); => {odd: 3, even: 2}
shuffle_.shuffle(list)
返回一个随机乱序的 list 副本, 使用 Fisher-Yates shuffle 来进行随机乱序.
_.shuffle([1, 2, 3, 4, 5, 6]); => [4, 1, 6, 3, 5, 2]
sample_.sample(list, [n])
从 list中产生一个随机样本。传递一个数字表示从list中返回n个随机元素。否则将返回一个单一的随机项。
_.sample([1, 2, 3, 4, 5, 6]); => 4 _.sample([1, 2, 3, 4, 5, 6], 3); => [1, 6, 2]
toArray_.toArray(list)
把list(任何可以迭代的对象)转换成一个数组,在转换 arguments 对象时非常有用。
(function(){ return _.toArray(arguments).slice(1); })(1, 2, 3, 4); => [2, 3, 4]
size_.size(list)
返回list的长度。
_.size({one: 1, two: 2, three: 3}); => 3
partition_.partition(array, predicate)
拆分一个数组(array)为两个数组: 第一个数组其元素都满足predicate迭代函数, 而第二个的所有元素均不能满足predicate迭代函数。
_.partition([0, 1, 2, 3, 4, 5], isOdd); => [[1, 3, 5], [0, 2, 4]]
数组函数(Array Functions)
注: arguments(参数) 对象将在所有数组函数中工作 。然而, Underscore 函数的设计并不只是针对稀疏("sparse" )数组的.
first_.first(array, [n])
Alias: head, take
返回array(数组)的第一个元素。传递 n参数将返回数组中从第一个元素开始的n个元素(愚人码头注:返回数组中前 n 个元素.)。
_.first([5, 4, 3, 2, 1]); => 5
initial_.initial(array, [n])
返回数组中除了最后一个元素外的其他全部元素。 在arguments对象上特别有用。传递 n参数将从结果中排除从最后一个开始的n个元素(愚人码头注:排除数组后面的 n 个元素)。
_.initial([5, 4, 3, 2, 1]); => [5, 4, 3, 2]
last_.last(array, [n])
返回array(数组)的最后一个元素。传递 n参数将返回数组中从最后一个元素开始的n个元素(愚人码头注:返回数组里的后面的n个元素)。
_.last([5, 4, 3, 2, 1]); => 1
rest_.rest(array, [index])
Alias: tail, drop
返回数组中除了第一个元素外的其他全部元素。传递 index 参数将返回从index开始的剩余所有元素 。(感谢@德德德德撸 指出错误)
_.rest([5, 4, 3, 2, 1]); => [4, 3, 2, 1]
compact_.compact(array)
返回一个除去所有false值的 array副本。 在javascript中, false, null, 0, "", undefined 和 NaN 都是false值.
_.compact([0, 1, false, 2, '', 3]); => [1, 2, 3]
flatten_.flatten(array, [shallow])
将一个嵌套多层的数组 array(数组) (嵌套可以是任何层数)转换为只有一层的数组。 如果你传递 shallow参数,数组将只减少一维的嵌套。
_.flatten([1, [2], [3, [[4]]]]); => [1, 2, 3, 4]; _.flatten([1, [2], [3, [[4]]]], true); => [1, 2, 3, [[4]]];
without_.without(array, *values)
返回一个删除所有values值后的 array副本。(愚人码头注:使用===表达式做相等测试。)
_.without([1, 2, 1, 0, 3, 1, 4], 0, 1); => [2, 3, 4]
union_.union(*arrays)
返回传入的 arrays(数组)并集:按顺序返回,返回数组的元素是唯一的,可以传入一个或多个 arrays(数组)。
_.union([1, 2, 3], [101, 2, 1, 10], [2, 1]); => [1, 2, 3, 101, 10]
intersection_.intersection(*arrays)
返回传入 arrays(数组)交集。结果中的每个值是存在于传入的每个arrays(数组)里。
_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]); => [1, 2]
difference_.difference(array, *others)
类似于without,但返回的值来自array参数数组,并且不存在于other 数组.
_.difference([1, 2, 3, 4, 5], [5, 2, 10]); => [1, 3, 4]
uniq_.uniq(array, [isSorted], [iteratee])
Alias: unique
返回 array去重后的副本, 使用 === 做相等测试. 如果您确定 array 已经排序, 那么给 isSorted 参数传递 true值, 此函数将运行的更快的算法. 如果要处理对象元素, 传递 iteratee函数来获取要对比的属性.
_.uniq([1, 2, 1, 3, 1, 4]); => [1, 2, 3, 4]
zip_.zip(*arrays)
将 每个arrays中相应位置的值合并在一起。在合并分开保存的数据时很有用. 如果你用来处理矩阵嵌套数组时,_.zip.apply 可以做类似的效果。
_.zip(['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]); => [["moe", 30, true], ["larry", 40, false], ["curly", 50, false]]
unzip_.unzip(*arrays)
与zip功能相反的函数,给定若干arrays,返回一串联的新数组,其第一元素个包含所有的输入数组的第一元素,其第二包含了所有的第二元素,依此类推。通过apply用于传递数组的数组。 (感谢 @周文彬1986、 @未定的终点 指出示例错误)
_.unzip([['moe', 'larry', 'curly'], [30, 40, 50], [true, false, false]]) => ["moe", 30, true], ["larry", 40, false], ["curly", 50, false]
object_.object(list, [values])
将数组转换为对象。传递任何一个单独[key, value]对的列表,或者一个键的列表和一个值得列表。 如果存在重复键,最后一个值将被返回。
_.object(['moe', 'larry', 'curly'], [30, 40, 50]); => {moe: 30, larry: 40, curly: 50} _.object([['moe', 30], ['larry', 40], ['curly', 50]]); => {moe: 30, larry: 40, curly: 50}
indexOf_.indexOf(array, value, [isSorted])
返回value在该 array 中的索引值,如果value不存在 array中就返回-1。使用原生的indexOf 函数,除非它失效。如果您正在使用一个大数组,你知道数组已经排序,传递true给isSorted将更快的用二进制搜索..,或者,传递一个数字作为第三个参数,为了在给定的索引的数组中寻找第一个匹配值。
_.indexOf([1, 2, 3], 2); => 1
lastIndexOf_.lastIndexOf(array, value, [fromIndex])
返回value在该 array 中的从最后开始的索引值,如果value不存在 array中就返回-1。如果支持原生的lastIndexOf,将使用原生的lastIndexOf函数。传递fromIndex将从你给定的索性值开始搜索。
_.lastIndexOf([1, 2, 3, 1, 2, 3], 2); => 4
查看更多:http://blog.zhengshuiguang.com/js/underscore-2.html
本文地址:http://blog.zhengshuiguang.com/js/underscore-1.html
转载随意,但请附上文章地址:-)
评论已关闭