javascript函数式编程库-underscore.js

javascript函数式编程库-underscore.js

javascript作为一门支持函数式编程的语言,衍生出一批优秀的函数式编程解决方案的第三方开源库。大名鼎鼎的jquery解决了js操作dom的难题,而underscore的出现则提供了一整套完整的函数式编程api

underscore几个常用的功能点总结:


Collection
  • map/filter
// 用于数组
console.log(_.map([1, 2, 3], (x) => x * x)) // [ 1, 4, 9 ]
console.log(_.filter([1,2,3], (x) => x > 1))
// 用于对象
console.log(_.map({a: 1, b: 2, c: 3}, (v, k) => k + "=" + v)) // [ 'a=1', 'b=2', 'c=3' ]
console.log(_.filter({a: 1, b: 2, c: 3}, (v, k) => k == 'a')) // [ 1 ]
// 用于对象2
console.log(_.mapObject({a: 1, b: 2, c: 3}, (v, k) => k + "=" + v)) // { a: 'a=1', b: 'b=2', c: 'c=3' }
  • every/some方法
// 数组
console.log(_.every([1, 2, 3, 'q'], (x) => _.isNumber(x))) // false
console.log(_.some([1, 2, 3, 'q'], (x) => _.isNumber(x))) // true
// 对象
console.log(_.every({a: 1, b: 2, c: 'q'}, (v, k) => _.isNumber(v))) // false
console.log(_.some({a: 1, b: 2, c: 'q'}, (v, k) => _.isNumber(v))) // true
  • max/min方法
// 数组
console.log(_.max([1, 2, 3])) // 3
console.log(_.min([1, 2, 3])) // 1
// 作用于对象只作用于value, 忽略key
console.log(_.max({a: 1, b: 2, c: 3})) // 3
console.log(_.min({a: 1, b: 2, c: 3})) // 1
  • groupBy()把集合的元素按照key归类,key由传入的函数返回
var scores = [20, 81, 75, 40, 91, 59, 77, 66, 72, 88, 99];
var groups = _.groupBy(scores, function (x) {
  if (x < 60) {
    return 'C'
  } else if (x < 80) {
    return 'B'
  } else {
    return 'A'
  }
})
console.log(groups)
// 结果:
// {
//   A: [81, 91, 88, 99],
//   B: [75, 77, 66, 72],
//   C: [20, 40, 59]
// }
  • shuffle/sample shuffle()用洗牌算法随机打乱一个集合,注意每次结果都不一样:
_.shuffle([1, 2, 3, 4, 5, 6]) // [3, 5, 4, 6, 2, 1]
// sample()则是随机选择一个或多个元素
// 注意每次结果都不一样:
// 随机选1个:
_.sample([1, 2, 3, 4, 5, 6]) // 2
// 随机选3个:
_.sample([1, 2, 3, 4, 5, 6], 3) // [6, 1, 4]
Array
  • first/last
console.log(_.first([1, 2, 3])) // 1
console.log(_.last([1, 2, 3])) // 3
  • faltten
// flatten()接收一个Array,无论这个Array里面嵌套了多少个Array,flatten()最后都把它们变成一个一维数组
console.log(_.flatten([1, [2], [3, [[4], [5]]]])) // [1, 2, 3, 4, 5]
  • zip/unzip/object
// zip()把两个或多个数组的所有元素按索引对齐,然后按索引合并成新数组
console.log(_.zip(['Adam', 'Lisa', 'Bart'], [85, 92, 59, 90]))
// [ [ 'Adam', 85 ],
//   [ 'Lisa', 92 ],
//   [ 'Bart', 59 ],
//   [ undefined, 90 ] ]
// unzip则是反过来
var namesAndScores = [['Adam', 85], ['Lisa', 92], ['Bart', 59]]
_.unzip(namesAndScores)
// [['Adam', 'Lisa', 'Bart'], [85, 92, 59]]
// object 有时候你会想,与其用zip(),为啥不把名字和分数直接对应成Object呢?别急,object()函数就是干这个的
console.log(_.object(['Adam', 'Lisa', 'Bart'], [85, 92, 59]))
  • range
console.log(_.range(10)) // [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
console.log(_.range(1, 11)) // [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]
console.log(_.range(0, 30, 5)) // [ 0, 5, 10, 15, 20, 25 ]
console.log(_.range(0, -10, -1)) // [ 0, -1, -2, -3, -4, -5, -6, -7, -8, -9 ]
  • uniq
// _.uniq(array, [isSorted], [iteratee]) 第二个参数表示是否是排序的,默认保留第一个元素,第三个参数是一个iteratee函数,用于变形后进行去重操作
var arr = ['Apple', 'orange', 'banana', 'ORANGE', 'apple', 'PEAR']
var result = _.uniq(arr,false,x => x.toUpperCase())
console.log(result)
// ["Apple", "orange", "banana", "PEAR"]
Function
  • bind
var s = 'hello'
s.trim = function () {console.log(s)}
var fn = _.bind(s.trim, s)
fn()
  • partial
// partial()就是为一个函数创建偏函数,它的作用就是固定住一个函数的某些参数,让函数的调用更加简单。
// 以Math.pow(x, y)为例
// 如果我们想固定底数
var pow2N = _.partial(Math.pow, 2)
pow2N(3) // 8
pow2N(5) // 32
pow2N(10) // 1024
// 如果我们想固定指数,第一个参数可以用‘_’做占位符
var powN3 = _.partial(Math.pow, _, 3)
console.log(powN3(3)) // 27
console.log(powN3(5)) // 125
console.log(powN3(10)) // 1000
  • memoize
// 如果一个函数调用开销很大,我们就可能希望能把结果缓存下来,以便后续调用时直接获得结果。举个例子,计算阶乘就比较耗时
var factorial = _.memoize(function(n) {
  console.log('start calculate ' + n + '!...')
  var s = 1, i = n
  while (i > 1) {
    s = s * i
    i --
  }
  console.log(n + '! = ' + s);
  return s
})

// 第一次调用:
factorial(10) // 3628800
// 注意控制台输出:
// start calculate 10!...
// 10! = 3628800

// 第二次调用:
factorial(10) // 3628800
// 控制台没有输出
  • once
// 顾名思义,once()保证某个函数执行且仅执行一次。如果你有一个方法叫register(),用户在页面上点两个按钮的任何一个都可以执行的话,就可以用once()保证函数仅调用一次,无论用户点击多少次
var register = _.once(function () {
  console.log('ok')
})
register()
register()
register()
// 只会执行一次
  • delay
// delay
// delay()可以让一个函数延迟执行,效果和setTimeout()是一样的,但是代码明显简单了
// 2秒后调用alert():
function show () {console.log('ok2')}
_.delay(show, 2000)
// 如果要延迟调用的函数有参数,把参数也传进去
var log = _.bind(console.log, console)
_.delay(log, 2000, 'Hello,', 'world!')
// 2秒后打印'Hello, world!':
Objects
  • key/allKeys
// key()返回对象所有的key,但不包括从原型链继承下来的
console.log(_.keys({a: 1, b: 2, c: 3})) // [ 'a', 'b', 'c' ]
// allKeys()包括从原型链继承下来的
function Student (name, age) {
  this.name = name
  this.age = age
}
Student.prototype.school = 'qddx'
console.log(_.allKeys(new Student('xiaoming', 20)))
  • values
// valueskeys()类似,values()返回object自身但不包含原型链继承的所有值,注意,没有allValues(),原因我也不知道
var obj = {
  name: '小明',
  age: 20
}
_.values(obj); // ['小明', 20]
  • mapObject
// mapObject()就是针对object的map版本
var obj = { a: 1, b: 2, c: 3 }
// 注意传入的函数签名,value在前,key在后:
console.log(_.mapObject(obj, (v, k) => 100 + v)) // { a: 101, b: 102, c: 103 }
  • invert
// invert()把object的每个key-value来个交换,key变成value,value变成key
var obj = {
  Adam: 90,
  Lisa: 85,
  Bart: 59
}
_.invert(obj) // { '59': 'Bart', '85': 'Lisa', '90': 'Adam' }
  • extend / extendOwn
// extend()把多个object的key-value合并到第一个object并返回
console.log(_.extend({a: 1}, {b: 2}, {c: {d:4}})) // { a: 1, b: 2, c: { d: 4 } }
// extendOwn() 与extend()类似,但获取属性时忽略从原型链继承下来的属性
  • clone
// clone() 是潜复制,也就是两个对象相同的key引用同一个value
console.log(_.clone({a:1, b:2, c:3}))
  • isEqual
// 对两个object进行深度比较, 内容相同返回true
console.log(_.isEqual({a:1, b:2, c:3}, {a:1, b:2, c:3}))
  • Chaining
// 链式调用,每一步返回的都是包装对象,最后需要通过value()获得最终结果
var r = _.chain([1, 3, 5, 7]).map(Math.sqrt).filter(x => x> 2).value()
console.log(r)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值