(_.merge in ES6/ES7)Object.assign 不覆盖未定义的值
Posted
技术标签:
【中文标题】(_.merge in ES6/ES7)Object.assign 不覆盖未定义的值【英文标题】:(_.merge in ES6/ES7)Object.assign without overriding undefined values 【发布时间】:2017-02-19 23:49:59 【问题描述】:lodash 中有_.merge 功能。我想在 ES6 或 ES7 中实现同样的目标。
有这个sn-p:
Object.assign(, key: 2, key: undefined)
我想收到key: 2
。目前我收到key: undefined
这不是深度合并。
有可能吗?如果是,那么如何实现呢?
【问题讨论】:
注意:这个问题不包括我未定义的情况:***.com/questions/13852852/… 你可以取第二个对象,剪除undefined
的任何值,然后在Object.assign
中使用它
@vlaz 是否有原生的 ES6 方法来从对象中删除 undefiend 值?
好吧,如果你只用一点 ES6 来使用 ES5,那么 arr.filter(x => typeof x !== "undefined" )
为什么你的对象中有未定义的值?只是想知道。
【参考方案1】:
如果你只需要值而不需要对象,你也可以使用对象解构:
const input = a: 0, b: "", c: false, d: null, e: undefined ;
const a = 1, b = 2, c = 3, d = 4, e = 5, f = 6 = input;
console.log(a, b, c, d, e, f);
// => 0, "", false, null, 5, 6
这只会覆盖缺失或未定义的值。
我经常将它用于函数参数的默认值,如下所示:
function f(options = )
const foo = 42, bar = options;
console.log(foo, bar);
f();
// => 42, undefined
f()
// => 42, undefined
f( foo: 123 )
// => 123, undefined
f( bar: 567 )
// => 42, 567
f( foo: 123, bar: 567 )
// => 123, 567
【讨论】:
【参考方案2】:使用 ES2019/ES10 的新对象方法 Object.fromEntries()
,可以更新 Michał 的 answer:
const assign = (target, ...sources) =>
Object.assign(target, ...sources.map(x =>
Object.fromEntries(
Object.entries(x)
.filter(([key, value]) => value !== undefined)
)
))
console.log(assign(, key: 2, key: undefined))
【讨论】:
【参考方案3】:使用 lodash 省略 nil 值,然后通过 spread 将两个对象合二为一
...(omitBy(key: 2, isNil)), ...(omitBy(key: undefined, isNil))
在此处查看有关 lodash 的更多信息https://lodash.com/docs/4.17.15
【讨论】:
【参考方案4】:您无法直接使用Object.assign
来实现这一点,因为每个下一个对象都会为上一个合并重写相同的键。唯一的方法是使用一些手工制作的函数来过滤传入的对象。
function filterObject(obj)
const ret = ;
Object.keys(obj)
.filter((key) => obj[key] !== undefined)
.forEach((key) => ret[key] = obj[key]);
return ret;
【讨论】:
你也可以将谓词作为参数传递,这样它就可以像Array.filter
我认为您在obj[key]
之后缺少一个结束)
@TechnoTim thnx,已修复
如何在deepmerge
中拥有相同的逻辑?【参考方案5】:
编写一个小工具来删除未定义的值:
function removeUndefined(obj)
for (let k in obj) if (obj[k] === undefined) delete obj[k];
return obj;
然后
Object.assign(, key: 2, removeUndefined(key: undefined))
这似乎比编写您自己的 assign
更可取,使用有线行为来删除未定义的值。
【讨论】:
这种方法会改变传入的对象,在某些情况下可能会出现问题【参考方案6】:您可以简单地过滤掉带有undefined
值的键,然后再将它们传递给Object.assign()
:
const assign = (target, ...sources) =>
Object.assign(target, ...sources.map(x =>
Object.entries(x)
.filter(([key, value]) => value !== undefined)
.reduce((obj, [key, value]) => (obj[key] = value, obj), )
))
console.log(assign(, key: 2, key: undefined))
【讨论】:
以上是关于(_.merge in ES6/ES7)Object.assign 不覆盖未定义的值的主要内容,如果未能解决你的问题,请参考以下文章