是否可以在单个语句中解构一个对象并生成一个新对象?

Is it possible to destructure an object and generate a new object in a single statement?

const {name, slug, description, parent} = cat;
const saneCat = {name, slug, description, parent};

在第一个表达式中,我们通过解构一个杂乱的对象来定义四个常量。在第二个表达式中,我们将它们组合成一个新对象。我想在不复制感兴趣字段列表的情况下一步完成此操作,但是因为第一个表达式没有定义对象,所以这似乎是不可能的。真的吗?我们离 Clojurian 的胜利如此之近!

我尝试了以下方法但没有成功。任何 ECMAScript 编译器都是公平的游戏,但我没有只使用 Clojurescript 的选项。

const saneCat = {name, slug, description, parent} = cat; // name is not defined
const {...saneCat} = {name, slug, description} = cat;  // name is not defined
const saneCat = ({name, slug, description, parent} = cat); // name is not defined
const saneCat = ({name, slug, description, parent}) = cat; // name is not defined
const saneCat = {{name, slug, description, parent}} = cat; // unexpected token
const saneCat = {{name, slug, description, parent}} = {cat}; // unexpected token

解构基本上是脱糖

({a} = obj}
// a = obj.a

({a: foo} = obj)
// foo = obj.a

({a: foo.bar} = obj)
// foo.bar = obj.a

所以从 obj 中取出一个键并将其放入另一个对象的唯一方法是在两者中重复键的名称,因为它没有简洁的形式,所以回答你的问题,你可以在技术上做到

const saneCat = {};
({
    name: saneCat.name,
    slug: saneCat.slug,
    description: saneCat.description,
    parent: saneCat.parent
} = cat);

但这非常难读,更难理解。我绝对建议使用现有的库或函数来执行此操作,例如 Lodash 的 pick:

const saneCat = _.pick(cat, ['name', 'slug', 'description', 'parent'])

不幸的是,ES6 中的解构仅限于赋值和参数列表。有一个 "pick" 运算符的讨论,它可以做你想做的事,但不要屏住呼吸。

同时,最接近的是以下内容,这需要复制属性列表:

const saneCat = 
  (({name, slug, description, parent}) => 
    ({name, slug, description, parent})
  )(cat);

使用建议的 pick 语法,您可以编写

const saneCat = {name, slug, description, parent} # cat;

类似的东西应该出现在 ES29 中。在那之前,您可以使用评论中提到的那种 pick 实用程序,但就个人而言,我 讨厌 将属性写为字符串。

另见 One-liner to take some properties from object in ES 6