Lodash用来操作对象和集合,比Underscore拥有更多的功能和更好的性能。
官网:https://lodash.com/
引用:<script src="//cdnjs.cloudflare.com/ajax/libs/lodash.js/2.4.1/lodash.min.js"></script>
安装:npm install lodash
首先通过npm安装lodash:
npm i --save lodash
在js文件中引用lodash:
var _ = require('lodash');
本系列包括:
● lodash用法系列(1),数组集合操作
● lodash用法系列(2),处理对象
● lodash用法系列(3),使用函数
● lodash用法系列(4),使用Map/Reduce转换
● lodash用法系列(5),链式
● lodash用法系列(6),函数种种
■ 类型隐式转换
true == 1;//右边的1会根据左边的true进行隐式转换 true === 1; //不会隐式转换
■ 判断参数是否是对象
function hello(greeting, person){ if(_.isPlainObject(greeting)){ person = greeting; greeting = 'hi'; } return greeting + person.name; } hello('hello',{name:''}); hello({name:''});
■ 判断计算结果
在Javascript中:
1/0;//Infinity
1+ '';//NaN
lodash中提供了isFinite, isNumber, isNaN方法。
var operand1 = 2/0 operand2 = NaN, results = []; _.forEach([operand1, operand2], function(op){ if(_.isFinite(op)){ results.push('结果无穷尽'); } else { if(!_.isNumber(op) || _.isNaN(op)){ results.push('结果不是数字'); } else { results.push('结果不正确'); } } }); console.log(results);
■ 判断对象是否是函数
var _ = require('lodash'); var o = { a: function(){return 'hi'}, b: [] }; //hi console.log(_.isFunction(o.a) && o.a()); //false console.log(_.isFunction(o.b) && o.b());
■ 给对象添加字段,相同字段值重写
var o = { name: '', age:22 }; _.assign(o, {occupation:''});
如果新添加的字段已经存在,会把该字段的值重写掉。
■ 给对象添加字段,合并字段值
如果新添加对象的字段存在,是否可以不把该字段的值重写掉呢?
--lodash提供了merge方法,有更加细粒度的控制。
var o1 = { states: {running: 'off'}, names: ['a','b'] }; var o2 = { states: {off: 'on'}, names: ['c','d'] }; var result = _.merge(o1, o2, function(dest, src){ if(_.isArray(dest) && _.isArray(src)){ return dest.concat(src); } }); //{ states: { running: 'off', off: 'on' },names: [ 'a', 'b', 'c', 'd' ] } console.log(result);
以上,o1和o2都有相同的字段,使用merge方法后会遍历o1与o2的所有字段,但可喜的是:如果o2和o1的字段相同,并没有进行简单的重写字段值,而是进行了合并。并且,还可以判断o1和o2的字段类型,如果是数组,就把两个数组concat。
■ 给对象添加字段,保持原来字段的值
var o = { name: 'a' }; _.defaults(o, { name: 'b' });
■ 根据对象的值寻找键,findKey方法接受匿名函数
var o = { name: 'a', age: 20 } var result = _.findKey(o, function(value){ return value === 'a'; }); //name console.log(result);
又比如。
var obj = { a: ['x','y'], b: ['m','n'] }; var search = 'x'; var result = _.findKey(obj, function(value){ if(_.isArray(value)){ return _.contains(value, search); } else { return value === search; } }); //a console.log(result);
■ 根据对象的值寻找键,findkey方法接受对象
var obj = { a: { name: 'a', age:20 }, b: { description:'' } }; var result = _.findKey(obj, {name: 'a'}); //a console.log(result);
■ 查询对象
var o = { 1: { first:'', enabled:false }, 2: { first: '', enabled:true } }; var result = _.find(o, 'enabled'); var result = _.where(o, {first: ''});
■ 遍历对象的字段
var o = { name: '', age:20, description:'' }; var result = []; _.forOwn(o, function(value, key){ result.push(key + ': ' + value); }); console.log(result);
可见,forOwn方法与forEach方法的不同之处在于匿名函数的第二个参数是键,不是索引。
■ 遍历对象的字段,对象有父对象
unction Person(){ this.full = function(){return this.first + ' ' + this.last;}; } function Employee(first, last, occupation){ this.first = first; this.last = last; this.occupation = occupation; } Employee.prototype = new Person(); var employee = new Employee('darren','ji','programmer'), resultOwn = [], resultIn = []; _.forOwn(employee, function(value, key){ resultOwn.push(key); }); //[ 'first', 'last', 'occupation' ] console.log(resultOwn); _.forIn(employee, function(value, key){ resultIn.push(key); }); //[ 'first', 'last', 'occupation', 'full' ] console.log(resultIn);
可见,forIn会遍历包括父对象的字段,forOwn只遍历当前对象的字段。
■ 获取对象的所有字段
var o1 = { occupation: '', last:'', first:'' }; var result1 = _.sortBy(_.keys(o1)); //[ 'first', 'last', 'occupation' ] console.log(result1);
■ 获取对象的所有字段,然后据此获取字段值
var o2 = { occupation: 'manager', last: 'ji', first: 'darren' }; //[ 'darren', 'ji', 'manager' ] console.log(_.at(o2, _.sortBy(_.keys(o2))));
■ 获取对象的所有字段值
var o = {}; _.values(o);
■ 当不确定对象某个字段是否是函数或其它时使用result方法
var o1 = {name: 'a'}, o2 = {name: function(){return 'b';}}, o3 = {}; console.log(_.result(o1,'name','darren'));//a console.log(_.result(o2, 'name','darren'));//b console.log(_.result(o3, 'name', 'darren'));//darren
■ 获取一个对象的所有方法名
function Person(first, last){ this.first = first; this.last = last; } Person.prototype.name = function(){ return this.first + ' ' + this.last; } //[ 'name' ] var result = _.functions(new Person('darren','ji')); console.log(result);
■ 把对象的键值对转换成数组元素
function format(label, value){ return label + ': ' + value; } var o = { first: 'darren', last: 'ji', age:33 },result = ''; var pairsResult = _.pairs(o); //[ [ 'first', 'darren' ], [ 'last', 'ji' ], [ 'age', 33 ] ] console.log(pairsResult); _.forEach(pairsResult, function(item){ result += format.apply(null, item) + ' '; }); //first: darren //last: ji //age: 33 console.log(result);
■ 选择对象中的某些字段
var o1 = { name: 'a', occupation:'b' }, o2 = { spcecialty: 'c', employer: 'd' }; //pick对象的字段 var o2pick = _.pick(o2, 'spcecialty'); //{ spcecialty: 'c' } console.log(o2pick); var result = _.assign(o1, o2pick); //{ name: 'a', occupation: 'b', spcecialty: 'c' } console.log(result);
■ 去除对象中的某些字段
_.omit(o2, 'employer');
去除字段值为bool,o, null的字段。
var o = { name: 'a', age:0, occupation:null, enabled: true }; var r = _.omit(o, function(value){ return !(!_.isBoolean(value) && value); }); //{ name: 'a' } console.log(r);
■ 颠倒对象的键和值
unction sortValues(object){ return _.values(object).sort(); } var o1 = { first: 'a', last: 'b' }, o2 = { first: 'c', last: 'd' }; //[ 'a', 'b' ] console.log(sortValues(o1)); [ 'first', 'last' ] console.log(sortValues(_.invert(o2)));
■ 创建对象
unction Person() { } Person.prototype.name = function () { return this.first + ' ' + this.last; } var arr = [ {first: 'aa', last: 'bb'}, {first: 'cc', last: 'dd'}, {first: 'ee', last: 'ff'}, ], people = []; _.forEach(arr, function(item){ people.push(_.create(Person.prototype, item)); }); //[ 'aa bb', 'cc dd', 'ee ff' ] console.log(_.invoke(people, 'name'));
以上,可以吧Person看作是一个接口或抽象类,通过prototype属性动态添加name方法。通过create方法动态把实例和Person.prototype绑定上。最后,通过invoke方法触发数组内Person元素的name方法。
■ 拷贝对象
function Person(first, last){ this.first = first; this.last = last; } var o1 = { first: 'darren', last: 'ji' }, o2 = new Person('jack','chen'), clone1 = _.clone(o1), clone2 = _.clone(o2); //darren console.log(clone1.first); //jack console.log(clone2.first);
参考资料:lodash in essential
未完待续~~