• lodash用法系列(2),处理对象


    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

    未完待续~~

  • 相关阅读:
    第八章 对象
    第七章 压缩列表
    第六章 整数集合
    Java中的Unsafe
    站在Java的角度看LinkedList
    Java内部类详解
    浅析Java中的final关键字
    ConcurrentHashMap
    阻塞队列
    线程池的使用和实现
  • 原文地址:https://www.cnblogs.com/darrenji/p/5011370.html
Copyright © 2020-2023  润新知