ES6 仅当属性已存在时才将属性复制到目标

ES6 copy properties to target only if they already exist

本文关键字:属性 复制 目标 存在 ES6      更新时间:2023-09-26

本质上是我想要的

let schema = {
       name: null,
       lastname: null
    }
let values = {
       name: "John",
       unwanted: "haxor"
    }

最终进入:

console.log(sanitized); // {name: "John", lastname: null}

--

使用Object.assign(schema, values)最终会得到不需要的值。

有没有简单的方法?

编辑:我应该补充一点,这是为了避免使用像lodash或underscore这样的库,所以如果解决方案过于复杂,它们将是更可取的解决方案。

没有内置的方法可以实现这一点。但是,有一种简单(几乎微不足道)的方法可以做到这一点:

const sanitized = {};
for (const p in schema)
    sanitized[p] = (p in object ? object : schema)[p];

只需从另一个对象检索相同的键:

Object.keys(schema).forEach(key => schema[key] = (key in values ? values : schema)[key]);

如果要创建新对象:

var newObj = {};
Object.keys(schema).forEach(key => newObj[key] = (key in values ? values : schema)[key]);

此外,这也与以前版本的 ES 兼容(当然,如果您不使用箭头功能)。

(key in values ? values : schema)[key])部分确保仅在第一个架构中的属性不会设置为undefined

编辑为OP稍微复杂的请求

只需将值和架构的键map到各个对象,然后将它们分散开来。优先考虑values,方法是将它们放在以下位置:

Object.assign(
  schema,
  ...Object.keys(schema).map(
    (key) => ({[key]: schema[key]})
  ),
  ...Object.keys(schema).map(
    (key) => ({[key]: values[key]})
  )
);

如果不想覆盖schema,请为Object.assign()指定其他target

let sanitized = Object.assign(
  {},
  ...Object.keys(schema).map(
    (key) => ({[key]: schema[key]})
  ),
  ...Object.keys(schema).map(
    (key) => ({[key]: values[key]})
  )
);

按照更接近@Bergi答案的模式,您可以使用Object.assign()做一些不那么冗长的事情:

let sanitized = Object.assign({}, ...Object.keys(schema).map(
    (key) => ({[key]: (key in values ? values : schema)[key]})
  )
);