Деструктуризация объекта в другой объект не работает - PullRequest
2 голосов
/ 06 мая 2020

Сегодня мне пришлось объединить два объекта, выбрав свойства объекта a и поместив их в объект b. Я не могу понять, почему первый синтаксис / оператор не работает, а второй - нет.

let user = { a: 1, b: 2 };
let data = { z: 1, c: 3, f: 8, d: 4 };

// Let's say I want user to be { a: 1, b: 2, c: 3}

// method 1 (not works) 
const r1 = {
    ...user,
    ...({c} = data)
};
document.getElementById("r1").innerText = JSON.stringify(r1);

// method 2 (works)
const r2 = {
    ...user,
    ...(({c}) => ({c}))(data)
};
document.getElementById("r2").innerText = JSON.stringify(r2);

Вы можете попробовать код на https://jsfiddle.net/Ljb7ndp4/6/

1 Ответ

2 голосов
/ 07 мая 2020

Во втором методе вы создаете IIFE (выражение немедленного вызова функции).

Из MDN docs , «IIFE (Immediately Invoked Function Expression) - это JavaScript функция, которая запускается, как только она определена». IIFE по методу 2 возвращает объект типа {c: <value>}. Поскольку объекты поддерживают оператор распространения, вы можете использовать его в определении объекта.

Чтобы визуализировать это в своем коде, вы можете присвоить результат IIFE переменной и распечатать результат на консоли.

const val = (({c}) => ({c}))(data)
console.log(val) // { c: 3 }

Синтаксис стрелочной функции в этом случае немного усложняет визуализацию происходящего, но код:

(({c}) => ({c}))(data);

является сокращенной версией этого, который, на мой взгляд, лучше читается.

(function(arg) {
  return { c: arg.c }
})(data);

Итак, мы можем преобразовать его в стрелочную функцию, чтобы понимать все преобразования, шаг за шагом.

Первоначально мы можем преобразовать функцию для использования синтаксиса стрелочной функции:

((arg) => {
  return { c: arg: c }
})(data)

Затем мы можем разрушить c из полученного аргумента.

(({c}) => {
  return { c: c }
})(data)

Как для созданной стрелочной функции не требуется блок, мы можем упростить ее:

// The parenthesis are added because the syntax () => {} is not valid.
(({c}) => ({ c: c }))(data)

И, наконец, мы можем использовать синтаксис коротких объектов, чтобы сделать его точно таким же, как исходный.

(({c}) => ({ c }))(data)

Итак, эта функция генерирует объект { c: <value> }, и поэтому вы можете использовать оператор распространения, чтобы объединить его с объектом, который вы строите.

...