【JavaScript】underscore
例:
'use strict'; _.map([1, 2, 3], (x) => x * x); // [1, 4, 9]
No1:
【every/some】
当集合的所有元素都满足条件时,_.every()
函数返回true
,当集合的至少一个元素满足条件时,_.some()
函数返回true
:
'use strict'; // 所有元素都大于0? _.every([1, 4, 7, -3, -9], (x) => x > 0); // false // 至少一个元素大于0? _.some([1, 4, 7, -3, -9], (x) => x > 0); // true
No2:
【max/min】
'use strict'; var arr = [3, 5, 7, 9]; _.max(arr); // 9 _.min(arr); // 3 // 空集合会返回-Infinity和Infinity,所以要先判断集合不为空: _.max([]) -Infinity _.min([]) Infinity
No3:
【groupBy】
groupBy()
把集合的元素按照key归类,key由传入的函数返回:
'use strict'; 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'; } }); // 结果: // { // A: [81, 91, 88, 99], // B: [75, 77, 66, 72], // C: [20, 40, 59] // }
No4:
【shuffle/sample】
shuffle()
用洗牌算法随机打乱一个集合
'use strict'; // 注意每次结果都不一样: _.shuffle([1, 2, 3, 4, 5, 6]); // [3, 5, 4, 6, 2, 1]
sample()
则是随机选择一个或多个元素:
'use strict'; // 注意每次结果都不一样: // 随机选1个: _.sample([1, 2, 3, 4, 5, 6]); // 2 // 随机选3个: _.sample([1, 2, 3, 4, 5, 6], 3); // [6, 1, 4]
No5:
【first/last】
'use strict'; var arr = [2, 4, 6, 8]; _.first(arr); // 2 _.last(arr); // 8
No6:
【flatten】
flatten()
接收一个Array
,无论这个Array
里面嵌套了多少个Array
,flatten()
最后都把它们变成一个一维数组:
'use strict'; _.flatten([1, [2], [3, [[4], [5]]]]); // [1, 2, 3, 4, 5]
No7:
【zip/unzip】
zip()
把两个或多个数组的所有元素按索引对齐,然后按索引合并成新数组。例如,你有一个Array
保存了名字,另一个Array
保存了分数,现在,要把名字和分数给对上,用zip()
轻松实现:
'use strict'; var names = ['Adam', 'Lisa', 'Bart']; var scores = [85, 92, 59]; _.zip(names, scores); // [['Adam', 85], ['Lisa', 92], ['Bart', 59]]
unzip()
则是反过来:
'use strict'; var namesAndScores = [['Adam', 85], ['Lisa', 92], ['Bart', 59]]; _.unzip(namesAndScores); // [['Adam', 'Lisa', 'Bart'], [85, 92, 59]]
No8:
【object】
把名字和分数直接对应成Object
'use strict'; var names = ['Adam', 'Lisa', 'Bart']; var scores = [85, 92, 59]; _.object(names, scores); // {Adam: 85, Lisa: 92, Bart: 59}
No9:
【range】快速生成一个序列
'use strict'; // 从0开始小于10: _.range(10); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] // 从1开始小于11: _.range(1, 11); // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] // 从0开始小于30,步长5: _.range(0, 30, 5); // [0, 5, 10, 15, 20, 25] // 从0开始大于-10,步长-1: _.range(0, -10, -1); // [0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
No10:
【bind】bind()
可以帮我们把s
对象直接绑定在fn()
的this
指针上,以后调用fn()
就可以直接正常调用了
'use strict'; var s = ' Hello '; var fn = _.bind(s.trim, s); fn(); // 输出Hello
当用一个变量fn
指向一个对象的方法时,直接调用fn()
是不行的,因为丢失了this
对象的引用。用bind
可以修复这个问题。
No11:
【partial】为一个函数创建偏函数
'use strict'; var pow2N = _.partial(Math.pow, 2); pow2N(3); // 8 pow2N(5); // 32 pow2N(10); // 1024
No12:
【memoize】自动缓存函数计算的结果
'use strict'; var factorial = _.memoize(function(n) { console.log('start calculate ' + n + '!...'); if (n < 2) { return 1; } return n * factorial(n - 1); }); factorial(10); // 3628800 // 输出结果说明factorial(1)~factorial(10)都已经缓存了: // start calculate 10!... // start calculate 9!... // start calculate 8!... // start calculate 7!... // start calculate 6!... // start calculate 5!... // start calculate 4!... // start calculate 3!... // start calculate 2!... // start calculate 1!... factorial(9); // 362880 // console无输出
No13:
【once】保证某个函数执行且仅执行一次
'use strict'; var register = _.once(function () { alert('Register ok!'); }); // 测试效果: register(); register(); register();
No14:
【delay】让一个函数延迟执行
'use strict'; // 2秒后调用alert(): _.delay(alert, 2000);
'use strict'; var log = _.bind(console.log, console); _.delay(log, 2000, 'Hello,', 'world!'); // 2秒后打印'Hello, world!':
No15:
【keys/allKeys】keys()
可以非常方便地返回一个object自身所有的key,但不包含从原型链继承下来的;allKeys()
除了object自身的key,还包含从原型链继承下来的:
'use strict'; function Student(name, age) { this.name = name; this.age = age; } var xiaoming = new Student('小明', 20); _.keys(xiaoming); // ['name', 'age']
'use strict'; function Student(name, age) { this.name = name; this.age = age; } Student.prototype.school = 'No.1 Middle School'; var xiaoming = new Student('小明', 20); _.allKeys(xiaoming); // ['name', 'age', 'school']
No16:
【values】返回object自身但不包含原型链继承的所有值
'use strict'; var obj = { name: '小明', age: 20 }; _.values(obj); // ['小明', 20]
No17:
【mapObject】针对object的map版本:
'use strict'; var obj = { a: 1, b: 2, c: 3 }; // 注意传入的函数签名,value在前,key在后: _.mapObject(obj, (v, k) => 100 + v); // { a: 101, b: 102, c: 103
No18:
【invert】把object的每个key-value来个交换,key变成value,value变成key
'use strict'; var obj = { Adam: 90, Lisa: 85, Bart: 59 }; _.invert(obj); // { '59': 'Bart', '85': 'Lisa', '90': 'Adam' }
No19:
【extend/extendOwn】多个object的key-value合并到第一个object并返回:
'use strict'; var a = {name: 'Bob', age: 20}; _.extend(a, {age: 15}, {age: 88, city: 'Beijing'}); // {name: 'Bob', age: 88, city: 'Beijing'} // 变量a的内容也改变了: a; // {name: 'Bob', age: 88, city: 'Beijing'}
extendOwn()
和extend()
类似,但获取属性时忽略从原型链继承下来的属性
No20:
【clone】复制
'use strict'; var source = { name: '小明', age: 20, skills: ['JavaScript', 'CSS', 'HTML'] }; var copied = _.clone(source); console.log(JSON.stringify(copied, null, ' '));
No21:
【isEqual】
'use strict'; var o1 = { name: 'Bob', skills: { Java: 90, JavaScript: 99 }}; var o2 = { name: 'Bob', skills: { JavaScript: 99, Java: 90 }}; o1 === o2; // false _.isEqual(o1, o2); // true
No22:
【chaining】链式调用
_.filter(_.map([1, 4, 9, 16, 25], Math.sqrt), x => x % 2 === 1); // [1, 3, 5] -----》修改 var r = _.chain([1, 4, 9, 16, 25]) .map(Math.sqrt) .filter(x => x % 2 === 1) .value(); console.log(r); // [1, 3, 5]
因为每一步返回的都是包装对象,所以最后一步的结果需要调用value()
获得最终结果