underscore提供了一套完善的函数式编程的接口,让我们更方便地在JavaScript中实现函数式编程。和jquery的全局变量$一样,underscore也提供了一个全局变量 _ ,方便我们调用其中的方法。
Arrays
underscore为Arrays提供了很多工具类方法,可以方便快捷的操作数组:
1.map
_.map([1,2,3],(x)=>2*x);//[2,4,6]
遍历数组的每一项,上例返回结果为[2,4,6]
2.first/last
let arr=[1,2,3,4];
_.first(arr);//1
_.last(arr);//4
分别获取数组的项和最后一项 ,上例分别返回 1 和 4
3.flatten
_.flatten([1,[2],[3,[[4],[5]]]]);
flatten接收一个数组作为参数,无论该数组中嵌套了多少个数组,该方法最后都把它们变成一个一维数组
4.zip/unzip
let names=['A','B','C'];
let ages=[17,18,19];
_.zip(names,ages);//[['A',17],['B',18],['C',19]]
let namesAndAges=[['A',17],['B',18],['C',19]];
_.unzip(namesAndAges);//[['A','B','C'],[17,18,19]]
5.Object
let names=['A','B','C'];
let ages=[17,18,19];
_.object(names,ages);//{A:17,B:18,C:19}
Functions
1.bind
let s=' hello ';
s.trim();//hello
let fn=s.trim;
fn();//报错
fn.call(s);//输出hello
//当用一个变量fn指向一个对象的方法时,直接调用fn()不行,以为丢失了this对象的引用。bind可以帮我们把对象直接绑定在fn()的this指针上
//bind用法如下:
let s=' hello ';
s.trim();//hello
let fn=_.bind(s.trim);
fn();
2.partial
为一个函数创建一个偏函数
假设我们要计算x的y次方,这时只需要调用 Math.pow(x, y)
就可以了。
假设我们经常计算2的y次方,每次都写 Math.pow(2, y)
就比较麻烦,如果创建一个新的函数能直接这样写pow2N(y)
就好了,这个新函数pow2N(y)
就是根据 Math.pow(x, y)
创建出来的偏函数,它固定住了原函数的第一个参数(始终为2):
let pow2N=_.partial(Math.pow,2);
pow2N(3);//8
pow2N(5)://32
如果不想固定第一个参数,想固定第二个参数,可用_作为占位符
let cube=_.partail(Math.pow,_,3);
cube(3);//27
cube(5);//125
3.delay
和 setTimeout效果一样
_.delay(alert,2000);
Objects
1.keys/allKeys
keys()
可以非常方便地返回一个object自身所有的key,但不包含从原型链继承下来的,allKeys()
除了object自身的key,还包含从原型链继承下来的:
function Student(){
this.name=name;
this.age=age;
}
let xiaoming=new Student("小明",12);
_.keys(xiaoming);//['name','age']
//allKeys
function Student(){
this.name=name;
this.age=age;
}
Student.prototype.school='qing hua da xue';
let xiaoming=new Student("小明",12);
_.allKeys(xiaoming);//['name','age','school']
2.values
和keys()
类似,values()
返回object自身但不包含原型链继承的所有值,注意,没有allValues()。
3.mapObject
let obj={a:1,b:2,c:3};
//value在前,key在后
_.mapObject(obj,(v,k)=>100+v);//{a:101,b:102,c:103}
4.invert
invert()
把object的每个key-value来个交换,key变成value,value变成key:
let obj={
A:20,
B:30,
C:40
}
_.invert(obj);//{'20':'A';'30':'B','40':'C'}
5.Extend/extendOwn
extend()
把多个object的key-value合并到第一个object并返回:
如果有相同的key,后面的object的value将覆盖前面的object的value。
extendOwn()
和extend()
类似,但获取属性时忽略从原型链继承下来的属性。
let a={name:'a',age:20};
_.extends(a,{age:15},{age:70,city:'New York'});//{name:'a',age:70,city:'New York'} 变量a的值也变了
a;//{name:'a',age:70,city:'New York'}
6.clone
如果我们要复制一个object对象,就可以用clone()
方法,它会把原有对象的所有属性都复制到新的对象中:
let source={
name:'小明',
age:20,
skills:['js','html']
}
let copied=_.clone(source);//{name:'小明',age:20,skills:['js','html']}
注意,clone()
是“浅复制”。所谓“浅复制”就是说,两个对象相同的key所引用的value其实是同一对象:
source.skills === copied.skills; // true
也就是说,修改source.skills
会影响copied.skills
。
7.isEqual
isEqual()
对两个object进行深度比较,如果内容完全相同,则返回true
:
let obj1={name:'A',skills:{java:90,js:99}};
let obj2={name:'B',skills:{js:99,jave:90}};
obj1===obj2;//false
_.isEqual(obj1,obj2);//true