ES
Object.assign(target, ...sources)
- 相同属性名且属性值是对象时,浅拷贝。
- 只会拷贝源对象自身的并且可枚举的属性到目标对象身上。
- 将
target
后的参数,都合并到target
上。
Object.assign(
{},
{ a: 1 },
{ b: { c: 2, d: 3 } },
{ b: { e: 4 } }
)
// { a: 1, b: { e: 4 } }
JQuery
$.extend([deep], target, object1, [objectN])
deep
布尔值,默认为false
,传true
时,遇到相同属性名且属性值是对象时,会合并属性值(深拷贝)。- 将
target
后的参数,都合并到target
上。
var object1 = { apple: 0, banana: {weight: 52, price: 100}, cherry: 97};
var object2 = { banana: {price: 200}, durian: 100};
// 修改原来的对象
$.extend(object1, object2);
// {apple: 0, banana: {price: 200}, cherry: 97, durian: 100}
object1 === {apple: 0, banana: {price: 200}, cherry: 97, durian: 100} // true
//合并对象到empty中,不会破坏原来的对象(object1)。
var empty = {}
var object = $.extend(empty, object1, object2);
empty === {apple: 0, banana: {price: 200}, cherry: 97, durian: 100} // true
object === empty // true
// 合并属性值
$.extend(true, {}, object1, object2);
// {apple: 0, banana: {weight: 52, price: 200}, cherry: 97, durian: 100}
lodash
assign
- 会忽略原型链上的属性。
- 会修改原来的对象。
把源对象(sources)的属性分配到目标对象(object),源对象会从左往右地调用,后面对象的属性会覆盖前面的。
assign(
{},
{ a: 1 },
{ b: { c: 2, d: 3 } },
{ b: { e: 4 } }
)
// { a: 1, b: { e: 4 } }
// 忽略原型链上的属性
function Foo() { this.c = 3; }
Foo.prototype.d = 4;
assign({ a: 1 }, new Foo());
// { a: 1, c: 3 }
// 会修改原来的对象
var test = { a: 1 };
assign(test, { b: 2 }); // { a: 1, b: 2 }
console.log(test); // { a: 1, b: 2 }
extend
- 会把原型链上的属性合并到目标对象。
- 会修改原来的对象。
在 3.x 版本中,extend
是 assign
的别名,它们的作用是一模一样的。
在 4.x 版本中,extend
是 assignIn
的别名,和 assign
有点区别。
// 把源对象原型链上的属性也合并到目标对象上
function Foo() { this.c = 3; }
Foo.prototype.d = 4;
extend({ a: 1 }, new Foo());
// { a: 1, c: 3, d: 4 }
merge
- 相同属性名且属性值是对象时,深拷贝。
- 会修改原来的对象。
merge
也和 assign
类似,不同的地方在于 merge
遇到相同属性的时候,如果属性值为纯对象(plain object)或者集合(collection)时,不是用后面的属性值去覆盖前面的属性值,而是会把前后两个属性值合并。如果源对象的属性值为 undefined
,则会忽略该属性。会修改原来的对象。
merge(
{},
{ a: 1 },
{ b: { c: 2, d: 3} },
{ b: { e: 4 } }
)
// { a: 1, b: { c: 2, d: 3, e: 4 } }
Immutable
merge
- 不会修改原来的对象。
- 相同属性名且属性值是对象时,浅拷贝。
Immutable.merge(
{},
{ a: 1 },
{ b: { c: 2, d: 3 } },
{ b: { e: 4 } }
)
// { a: 1, b: { e: 4 } }
mergeDeep
- 不会修改原来的对象。
- 相同属性名且属性值是对象时,深拷贝。
Immutable.mergeDeep(
{},
{ a: 1 },
{ b: { c: 2, d: 3} },
{ b: { e: 4 } }
)
// { a: 1, b: { c: 2, d: 3, e: 4 } }
性能对比
对象合并,循环 10,000次,耗时对比。
浅拷贝
ES: 6 ms (Object.assign)
Jquery: 6 ms ($.extend(false, target, object1, [objectN]))
lodash: 10 ms (assign、extend)
Immutable: 211 ms (merge)
深拷贝
Jquery: 26 ms ($.extend(true, target, object1, [objectN]))
lodash: 41 ms (merge)
Immutable: 247 ms (mergeDeep)