lodash 中文学习拾零之 Object篇

本文介绍了lodash中处理Object的各种方法,包括判断Object类型、赋值与取值、查找keys和values、遍历对象、转化对象以及创建和克隆对象等。详细讲解了如_.assign、_.merge、_.defaults、_.findKey、_.forOwn等关键函数的使用,帮助开发者更高效地操作JavaScript对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者:Soaring_Tiger 转载请注明出处 http://blog.youkuaiyun.com/Soaring_Tiger

前情提要1 : lodash中文学习拾零之Array篇
前情提要2:lodash 中文学习拾零之 Chain篇
前情提要3:lodash 中文学习拾零之 Collection篇

4. 处理哪些Object?

lodash的Object方法处理的是:function, array, string, JSON


4.1 判断Object类型

lodash提供了一系列用于判断Obejct类型的方法,称为 variadic functions
_.isString
_.isArray
_.isTypedArray
_.isNumber
_.isBoolean
_.isDate
_.isPlainObject
_.isRegExp
_.isFunction
_.isObject
_.isPlainObject
_.isFinite
_.isElement
_.isNative
_.isUndefined
_.isNull
_.isNaN

//例如下面这个 _.isString用来判断输入的参数是否是String类型
function hello(name) {
       if (_.isString(name)) {
           return 'hello, ' + name;
       }
}
   hello('world');
   // → "hello, world"
   hello();
   // → undefined
//判断是否是函数的参数
_.isArguments(function() { return arguments; }());
// → true

_.isArguments([1, 2, 3]);
// → false
//判断是否语言意义上的Object: 
//(e.g. arrays, functions, objects, regexes, new Number(0), and new String(''))
_.isObject({});
//true

_.isObject([1, 2, 3]);
//true

_.isObject(1);
//false
//判断是否 plain object
function Foo() {
  this.a = 1;
}

_.isPlainObject(new Foo);
// → false

_.isPlainObject({a:1});
// → true

4.2 赋值与取值(Assigning and accessing properties)

创建一个javascript object对象并对之赋值是个常见工作,其中有些过程挺无聊的,比如:把一个对象的部分数据搞到另一个里去、或者必须确保为新对象填充默认值、确定是否存在某个key并且准确的赋值……
不用慌,对于上述等等无聊的事情,lodash提供了一系列工具来让你轻松完成。


4.2.1 扩展对象(Extending objects)

4.2.1.1 _.assign(object, [sources], [customizer], [thisArg])

注意[sources]这个参数,理论上可以是无限多,缺省情况下,后面的同名Key:Value对会覆盖前面的值。

的返回值一定是个Object

var object = {
       name: '汤姆',
       age: 42 
};

_.assign(object, {occupation: '程序猿'},{'name':'杰瑞'});
//注意,此处新的 name:'杰瑞' 覆盖了原有的数据 '汤姆'
// → 
// {
//   name: "杰瑞",
//   age: 42,
//   occupation: "程序猿"
// }


// 设计自定义的回调函数
var defaults = _.partialRight(_.assign, function(value, other) {
  return _.isUndefined(value) ? other : value;
});

defaults(object, { 'language': 'JS' }, { 'name': '果菲' });
// 原来没有的属性language及其值被添加了上去,而'name'的值还是保持不变
// → { 
//      'name': '杰瑞', 
//      'age': 42,
//      'occupation':'程序猿',
//      'language':'JS'
//   }

4.2.1.2 _.merge(object, [sources], [customizer], [thisArg])

采用递归的方式将sources objects合并到目标Object当中,后面的相同属性会覆盖前面的相同属性。

_.merge (合并器)的
第一个参数是目标Object
第二个参数是源Object(即要合并进来的内容)
第三个参数是自定义处理器并接受五个参数(objectValue, sourceValue, key, object, source)

.merge的返回值一定是个Object

var users = {
  'data': [{ 'user': '钱夫人' }, { 'user': '阿土伯' }]
};

var ages = {
  'data': [{ 'age': 36 }, { 'age': 50 }]
};

_.merge(users, ages);
// → { 'data': 
//      [
//          { 'user': '钱夫人', 'age': 36 }, 
//          { 'user': '阿土伯', 'age': 50 }
//      ] 
//  }
var object1 = {
           states: { running: 'poweroff' },
           names: [ 'CentOS', 'REHL' ]
       },
       object2 = {
           states: { off: 'poweron' },
           names: [ 'Ubuntu', 'Debian' ]
        };

_.merge(object1, object2, function(a, b) {
        if (_.isArray(a)) {
            return a.concat(b);
        }
    });
// → 
// {
// states: {
//     running: "poweroff",
//     off: "poweron"
// },
// names: [
//       "CentOS",
//       "REHL",
//       "Ubuntu",
//       "Debian"
//   ]
// }
//注意下面的例子的差别:
_.merge({a:[20,30]},[1,2]);
//{"0":1,"1":2,"a":[20,30]}

_.merge([1,2],{a:[20,30]});
//[1,2]

扩展对象小结

.merge 与 .assign 的相似之处在于:都是把source object数据加到目标object中;
不同之处在于.assign 会直接将source object的property覆盖目标object,不会考虑差异; 而.merge则会比较两者的property细节,已存在的会被覆盖,新的则会添加上去。


4.2.2 缺省值

用于设定object缺省值

4.2.2.1 _.defaults(object, [sources])

目标Object中设定的值是缺省值,不能被sources的相同property覆盖

_.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' });
// → { 'user': 'barney', 'age': 36 }

_defaults([1,2],[3,4,5]);
// → [1,2,5]

4.2.2.2 _.defaultsDeep(object, [sources])

与defaults类似,但是用递归的方式分配默认值

_.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } });
// → { 'user': { 'name': 'barney', 'age': 36 } }

4.3 查找keys和values

4.3.1_.findKey(object, [predicate=_.identity], [thisArg])

有点类型于Collection方法里的_.find,但是返回的是被匹配的Key的值(string|undefined)

var users = {
  'barney':  { 'age': 36, 'active': true },
  'fred':    { 'age': 40, 'active': false },
  'pebbles': { 'age': 1,  'active': true }
};

_.findKey(users, function(chr) {
  return chr.age < 40;
});
// → 'barney' (iteration order is not guaranteed)

// using the `_.matches` callback shorthand
_.findKey(users, { 'age': 1, 'active': true });
// → 'pebbles'

// using the `_.matchesProperty` callback shorthand
_.findKey(users, 'active', false);
// → 'fred'

// using the `_.property` callback shorthand 
_.findKey(users, 'active');
// → 'barney' 注意这个值和上一个值的区别
//使用迭代器处理复杂查找的例子:
var object = {
       Maria: [
           'Python',
           'Lisp',
           'Go'
        ], 
    Douglas: [
           'CSS',
           'Clojure',
           'Haskell'
        ] 
};

var lang = 'Lisp';

//通过迭代器检查数据类型
_.findKey(object, function(value) {
   if (_.isArray(value)) {
           return _.contains(value, lang);
       } else {
           return value === lang;
} });
// → "Maria"

4.3.2_.findLastKey(object, [predicate=_.identity], [thisArg])

_.findLastKey查找的是最后一个符合条件的key

var users = {
  'barney':  { 'age': 36, 'active': true },
  'fred':    { 'age': 40, 'active': false },
  'pebbles': { 'age': 1,  'active': true }
};

_.findLastKey(users, function(chr) {
  return chr.age < 40;
});
// → returns `pebbles` 对比一下前面的例子 `_.findKey` 返回的是 `barney`

4.4 遍历对象(Iterating over objects)

4.4.1 基础遍历(Basic For Each)

4.4.1.1_.forOwn(object, [iteratee=_.identity], [thisArg])

实际上,当遍历的对象都是一个Object时,forOwn与Collection方法中的forEach的作用是完全相同的,因为它们都有共同的 base function

var object = {
       name: 'Vince',
       age: 42,
       occupation: 'Architect'
   }, result = [];

_.forOwn(object, function(value, key) {
       result.push(key + ': ' + value);
}); 

// →
// [
//   "name: Vince",
//   "age: 42",
//   "occupation: Architect"
// ]

function Foo() {
  this.a = 1;
  this.b = 2;
}
//下面的例子说明:(1function也是object;(2)prototype不是"Own Key"
function Foo() {
  this.a = 1;
  this.b = 2;
}

Foo.prototype.c = 3;

_.forOwn(new Foo, function(value, key) {
  console.log(key);
});
// → logs 'a' and 'b' (iteration order is not guaranteed)

4.4.1.2_.forOwnRight(object, [iteratee=_.identity], [thisArg])

遍历方向与forOwn相反。


4.4.2 搜索继承属性 Including inherited properties

_.forOwn无法检索继承下来的属性,所以要检索继承的属性就要用 forIn和 forInRight了。

4.4.2.1_.forIn(object, [iteratee=_.identity], [thisArg])

function Foo() {
  this.a = 1;
  this.b = 2;
}

Foo.prototype.c = 3;

_.forIn(new Foo, function(value, key) {
  console.log(key);
});
// → logs 'a', 'b', and 'c' 

4.4.2.2_.forInRight(object, [iteratee=_.identity], [thisArg])

与_.forIn的次序相反


4.5 Keys和Values

4.5.1 Keys

4.5.1.1 _.keys(object)

获得object的所有own key,返回值为数组

function Foo() {
  this.a = 1;
  this.b = 2;
}

Foo.prototype.c = 3;

_.keys(new Foo);
// → ['a', 'b'] (prototype.c 没有被包含在内)

_.keys('hi');
// → ['0', '1'] (string被当成数组,01就是'h''i'的key)

4.5.1.2 _.keysIn(object)

获得object的所有key,prototype也包含在内


4.5.2 Values

4.5.2.1 _.values(object)

获得Object所有的own key的值

function Foo() {
  this.a = 1;
  this.b = 2;
}

Foo.prototype.c = 3;

_.values(new Foo);
// → [1, 2] 

_.values('hi');
// → ['h', 'i']

4.5.2.2 _.valuesIn(object)

获得Object所有Key的值,prototype的值也包括在内。

function Foo() {
  this.a = 1;
  this.b = 2;
}

Foo.prototype.c = 3;

_.valuesIn(new Foo);
// → [1, 2, 3] (iteration order is not guaranteed)

4.6 调用方法

4.6.1_.result(object, path, [defaultValue])

第一个参数是Object,第二个参数是被调用的方法(或属性)的路径,第三个参数是缺省值

var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] };

_.result(object, 'a[0].b.c1');
// → 3

_.result(object, 'a[0].b.c2');
// → 4

_.result(object, 'a.b.c', 'default');
// → 'default'

_.result(object, 'a.b.c', _.constant('default'));
// → 'default'

4.6.2 _.functions(object)

列出object的所有方法

function Person(first, last) {
       this.first = first;
       this.last = last;
}

Person.prototype.name = function() {
    return this.first + ' ' + this.last;
};
_.functions(new Person('Teresa', 'Collins'));
// → [ "name" ]

4.7 转化对象(Transforming objects)

有时候,我们手上的对象并不能满足我们的需要,而要转成其他形式的数据结构,而lodash刚好提供了一批这样的工具。

4.7.1 _.pairs(object)

将对象转为数组

_.pairs({ 'barney': 36, 'fred': 40 });
// → [['barney', 36], ['fred', 40]] 

4.7.2 _.pick(object, [predicate], [thisArg])

挑选对象的特定的property,并返回一个新的object

var object1 = {
           name: 'Kevin Moore',
           occupation: 'Programmer'
       },
   object2 = {
           specialty: 'Python',
           employer: 'Acme'
    };

_.assign(object1, _.pick(object2, 'specialty'));
   // →
   // {
   //   name: "Kevin Moore",
   //   occupation: "Programmer",
   //   specialty: "Python"
   // }

4.7.3 _.omit(object, [predicate], [thisArg])

扔掉指定的property,返回一个新的Object

var object1 = {
           name: 'Kevin Moore',
           occupation: 'Programmer'
       },
       object2 = {
           specialty: 'Python',
           employer: 'Acme'
    };

   _.assign(object1, _.omit(object2, 'employer'));
   // →
   // {
   //   name: "Kevin Moore",
   //   occupation: "Programmer",
   //   specialty: "Python"
   // }
var object = { 'user': 'fred', 'age': 40 };

_.omit(object, 'age');
// → { 'user': 'fred' }

_.omit(object, _.isNumber);
// → { 'user': 'fred' }

4.7.4 _.invert(object, [multiValue])

颠倒key和value,第二个参数为是否接受多个值

var object = { 'a': 1, 'b': 2, 'c': 1 };

_.invert(object);
// → { '1': 'c', '2': 'b' }

// with `multiValue`
_.invert(object, true);
// → { '1': ['a', 'c'], '2': ['b'] }

4.8 创建和克隆对象

4.8.1_.create(prototype, [properties])

创建对象

function Shape() {
  this.x = 0;
  this.y = 0;
}

function Circle() {
  Shape.call(this);
}

Circle.prototype = _.create(Shape.prototype, {
  'constructor': Circle
});

var circle = new Circle;
circle instanceof Circle;
// → true

circle instanceof Shape;
// → true

4.8.2 _.clone(value, [isDeep], [customizer], [thisArg])

克隆对象

function Person(first, last) {
       this.first = first;
       this.last = last;
}

var object1 = {
           first: 'Laura',
           last: 'Gray'
       },
       object2 = new Person('Bruce', 'Price'),
       clone1 = _.clone(object1),
       clone2 = _.clone(object2);
   clone1.first === 'Laura';
   // → true
   clone2.first === 'Bruce' && clone2 instanceof Person;
   // → false

4.8.3 _.cloneDeep(value, [customizer], [thisArg])

深度克隆

var users = [
  { 'user': 'barney' },
  { 'user': 'fred' }
];

var deep = _.cloneDeep(users);
deep[0] === users[0];
// → false

// using a customizer callback
var el = _.cloneDeep(document.body, function(value) {
  if (_.isElement(value)) {
    return value.cloneNode(true);
  }
});

el === document.body
// → false
el.nodeName
// → BODY
el.childNodes.length;
// → 20
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值