认识Underscore
Underscore一个JavaScript实用库,提供了一整套函数式编程的实用功能,但是没有扩展任何JavaScript内置对象。它弥补了部分jQuery没有实现的功能,同时又是Backbone.js必不可少的部分。
中文API: http://www.css88.com/doc/underscore/
英文API: http://underscorejs.org/
GitHub仓库: https://github.com/jashkenas/underscore
Underscore没有对原生的javascript进行扩展,而是调用 _() 方法进行封装。封装后javascript对象就成了一个Underscore对象,可以使用Underscore定义的各种方法。
集合函数 (数组 或对象) Collection Functions (Arrays or Objects)
each: _.each(list, iteratee, [context]) 如果传递了context参数,则把iteratee绑定到context对象上 每次调用iteratee都会传递三个参数:(element/value, index/key, list)
map: _.map(list, iteratee, [context]) 通过转换函数(iteratee迭代器)映射列表中的每个值生成新的数组 每次调用iteratee都会传递三个参数:(element/value, index/key, list)
find: _.find(list, predicate, [context])
在list中逐项查找,返回第一个通过predicate迭代函数真值检测的元素值,如果没有值传递给测试迭代器将返回undefined
。 如果找到匹配的元素,函数将立即返回,不会遍历整个list。
filter: _.filter(list, predicate, [context])
遍历list中的每个值,返回包含所有通过predicate检测的值的新数组。
max min: _.max(list, [iteratee], [context])
_.min(list, [iteratee], [context])
返回list中的最大值 最小值。如果传递iteratee参数,iteratee将作为list中每个值的排序依据。如果list为空,将返回-Infinity。
sortBy: _.sortBy(list, iteratee, [context])
返回一个排序后的list拷贝副本。如果传递iteratee参数,iteratee将作为list中每个值的排序依据。迭代器也可以是字符串的属性的名称进行排序的(比如 length)。
groupBy: _.groupBy(list, iteratee, [context]) 把一个集合分组为多个集合,通过 iterator 返回的结果进行分组. 如果 iterator 是一个字符串而不是函数, 那么将使用iterator 作为各元素的属性名来对比进行分组。
//each var arr = [1,2,3] _.each(arr,function(n){ console.log( n ) }) var obj = {one: 1, two: 2, three: 3} _.each(obj,function(i){ console.log( 'v'+ i ) }) //map var arr = [1,2,3] var newArr = _.map(arr,function(n){ return n + 5 }) console.log( newArr ) //[6,7,8] var obj = {one: 1, two: 2, three: 3} var newObj = _.map(obj,function(i){ return 'v'+ i }) console.log( newObj ) //["v1", "v2", "v3"] //find var arr = [1, 2, 3, 4, 5, 6] var even = _.find(arr, function(num){ return num % 2 == 0 }) console.log( even ) //2 //filter var arr = [1, 2, 3, 4, 5, 6] var evens = _.filter(arr, function(num){ return num % 2 == 0 }) console.log( evens ) //[2, 4, 6] //max min var arr = [1, 2, 3]; var _arr = _(arr); console.log( _arr.max() +'_'+ _arr.min() ) // 3_1 var person = [ {name: 'a', age: 10}, {name: 'b', age: 20}, {name: 'c', age: 30} ] var maxAgeName = _.max(person,function(n){ return n.age }) console.log( maxAgeName.name +'_'+ maxAgeName.age ) //c_30 var minAgeName = _.min(person,function(n){ return n.age }) console.log( minAgeName.name +'_'+ minAgeName.age ) //a_10 //sortBy var arr = [1, 2, 3, 4, 5, 6]; var _arr = _.sortBy(arr,function(num){ return Math.sin(num) }) console.log(_arr) // [5, 4, 6, 3, 1, 2] var person = [ {name: 'a', age: 80}, {name: 'b', age: 20}, {name: 'c', age: 40} ] var personB = _.sortBy(person,function(n){ return n.age }) console.log(personB) //[{name: 'b', age: 20}, {name: 'c', age: 40}, {name: 'a', age: 80}] //groupBy var arr = [1, 2, 3, 4, 5, 6]; var _arr = _.groupBy(arr,function(num){ return num > 3 }) console.log(_arr) // object {false: [1,2,3], true: [4,5,6]} var person = [ {name: 'a', age: 80}, {name: 'b', age: 20}, {name: 'c', age: 40} ] var personB = _.groupBy(person,function(n){ return n.age > 40 }) console.log(personB) //Object { false: [{name: 'b', age: 20}, {name: 'c', age: 40}], true: [{name: 'a', age: 80}] }
数组函数(Array Functions)
first: _.first(array, [n])
返回array(数组)的第一个元素。传递 n参数将返回数组中从第一个元素开始的n个元素, 返回数组中前 n 个元素。
last: _.last(array, [n])
返回array(数组)的最后一个元素。传递 n参数将返回数组中从最后一个元素开始的n个元素, 返回数组里的后面的n个元素。
indexOf: _.indexOf(array, value, [isSorted])
返回value在该 array 中的索引值,如果value不存在 array中就返回-1。
lastIndexOf: _.lastIndexOf(array, value, [fromIndex])
返回value在该 array 中的从最后开始的索引值,如果value不存在 array中就返回-1。
without: _.without(array, *values)
返回一个删除所有values值后的 array副本
union: _.union(*arrays)
返回传入的 arrays(数组)并集:按顺序返回,返回数组的元素是唯一的,可以传入一个或多个 arrays(数组)。
//first var person = [ {name: 'a', age: 80}, {name: 'b', age: 20}, {name: 'c', age: 40} ] var personA = _.first(person) var personB = _.first(person,[2]) console.log(personA) // {name: 'a', age: 80} console.log(personB) // [ {name: 'a', age: 80},{name: 'b', age: 20}] //last var person = [ {name: 'a', age: 80}, {name: 'b', age: 20}, {name: 'c', age: 40} ] var personA = _.last(person) var personB = _.last(person,[2]) console.log(personA) // {name: 'c', age: 40} console.log(personB) // [{name: 'b', age: 20}, {name: 'c', age: 40}] //indexOf var arr = [1,2,3,4,5] var find = _.indexOf(arr,2) console.log(find) //1 //lastIndexOf var arr = [1,2,3,4,5,3,2,1,3,6] var find = _.lastIndexOf(arr,3,7) console.log(find) //5 //without var arr = [1,2,3,4,5,3,2,1,3,6] var newArr = _.without(arr,1,2,3) console.log(newArr) //[4, 5, 6] //union var arr1 = [1,2,3], arr2 = [2,3,4], arr3 = [3,4,5] var newArr = _.union(arr1,arr2,arr3) console.log(newArr) //[1, 2, 3, 4, 5]
与函数有关的函数(Function (uh, ahem) Functions)
bindAll: _.bindAll(object, *methodNames)
把methodNames参数指定的一些方法绑定到object上,这些方法就会在对象的上下文环境中执行。主要是把这些方法与某个页面元素相绑定 ,否则函数被调用时this一点用也没有。
delay: _.delay(function, wait, *arguments)
类似setTimeout,等待wait毫秒后调用function。如果传递可选的参数arguments,当函数function执行时,arguments 会作为参数传入。
once: _.once(function)
创建一个只能调用一次的函数。重复调用改进的方法也没有效果,只会返回第一次执行时的结果。 作为初始化函数使用时非常有用, 不用再设一个boolean值来检查是否已经初始化完成。
wrap: _.wrap(function, wrapper) 将第一个函数 function 封装到函数 wrapper 里面, 并把函数 function 作为第一个参数传给 wrapper. 这样可以让wrapper 在 function 运行之前和之后 执行代码, 调整参数然后附有条件地执行。
compose: _.compose(*functions)
返回函数集 functions 组合后的复合函数, 也就是一个函数执行完之后把返回的结果再作为参数赋给下一个函数来执行. 以此类推. 在数学里, 把函数 f(), g(), 和 h() 组合起来可以得到复合函数 f(g(h()))。
//bandAll var person = { id: '#div', text: 'hello world', onClick: function(){ $(this.id).html(this.text) } } _.bindAll(person, 'onClick') //delay var fun = function(v){ console.log( v ) } _.delay(fun,1000,'hello world') //once var a = 1, b = 'A', fun = function(){ a++ b += 'B' } /* fun() //1 a => 2, b => 'AB' console.log( a ) console.log( b ) fun() //2 a => 3, b => 'ABB' console.log( a ) console.log( b ) */ var init = _.once(fun) init() //1 a => 2, b => 'AB' console.log( a ) console.log( b ) init() //2 a => 2, b => 'AB' console.log( a ) console.log( b ) //wrap var hello = function(name){ return "hello: " + name } hello = _.wrap(hello, function(func){ return "before, " + func("moe") + ", after" }) console.log( hello() ) //compose var A = function(v){ return v * v } var B = function(v){ return v * v } var C = function(v){ return v * v } var D = _.compose(A,B,C) var E = D(2) var F = A(B(C(2))) console.log( E ) // 256 console.log( F ) // 256
对象函数(Object Functions)
keys: _.keys(object) 检索并返回object拥有的所有可枚举属性的名称 返回一个数组
values: _.values(object)
返回object对象所有的属性值 返回一个数组
pick: _.pick(object, *keys)
返回一个object中列入挑选key属性的对象
omit: _.omit(object, *keys) 返回一个object中没有列入排除key属性的对象
defaults: _.defaults(object, *defaults)
用defaults设置object 中的默认属性值, 并且返回这个object。一旦这个属性被填充,再使用defaults方法将不会有任何效果。
has: _.has(object, key)
对象是否包含给定的键吗? 等同于object.hasOwnProperty(key),但是使用hasOwnProperty 函数的一个安全引用,以防意外覆盖。
//keys var person = { name: 'lbs', age: 10 } var personKeys = _.keys(person) console.log( personKeys ) // ["name", "age"] //values var person = { name: 'lbs', age: 10 } var personValues = _.values(person) console.log( personValues ) // ["lbs", 10] //pick var data = { a: 1, b: 2, c: 3, d: 4 } var newData = _.pick(data,'a','c') console.log( newData ) //Object {a: 1, c: 3} //omit var data = { a: 1, b: 2, c: 3, d: 4 } var newData = _.omit(data,'a','c') console.log( newData ) //Object {b: 2, d: 4} //defaults var person = { name: 'lbs', age: 10 } _.defaults(person,{name:'ccx',sex:'girl'}) //name在此无效 console.log( person ) //Object {name: "lbs", age: 10, sex: "girl"} //has var data = { a: 1, b: 2, c: 3, d: 4 } console.log( _.has(data, 'b') )//true
实用功能(Utility Functions)
random: _.random(min, max)
返回一个min 和 max之间的随机整数(包括min和max)。如果你只传递一个参数,那么将返回0和这个参数之间的整数。
escape: _.escape(string)
编码字符串,替换 &, <, >, ", ', / 字符。
unescape: _.unescape(string)
解码字符串,替换&, <, >, ", `, /字符
template: _.template(templateString, [settings])
将 JavaScript 模板编译为可以用于页面呈现的函数, 对于通过JSON数据源生成复杂的HTML并呈现出来的操作非常有用。 模板函数可以使用 <%= … %>插入变量, 也可以用<% … %>执行任意的 JavaScript 代码。
//random var num = _.random(10) // _.random(0,10) //var num = _.random(-10,10) //包括-10 和 10 这两个数字 console.log(num) //escape var str = _.escape('A, B & C') console.log( str ) //A, B & C //unescape var str = _.unescape('A, B & C') console.log( str ) // A, B & C //template var compiled = _.template("hello: <%= name %>"); console.log( compiled({name: 'lbs'}) ) // hello: lbs //...
链式语法(Chaining)
value: 获取封装对象中原生javascript对象的数据 获取封装对象的最终值。
chain: _.chain(obj) 返回一个封装的对象. 在封装的对象上调用方法会返回封装的对象本身, 直道 value 方法调用为止(调用后可以采取链式写法逐层获取返回值)。
//value var data = { name: 'lbs', age: 10 } var _data = _(data); console.log( _data.value().name ) //lbs //chain var person = [ {name: 'a', age: 80}, {name: 'b', age: 20}, {name: 'c', age: 40} ] var youngest = _.chain(person).sortBy(function(n){ return n.age }).map(function(n){ return n.name +' is '+ n.age }).first().value(); console.log( youngest ) //b is 20
// ]]>