Я пытаюсь выяснить, можно ли обрабатывать несколько уровней параметров по умолчанию с деструктурированием. Так как на словах объяснить не просто, вот пошаговый пример...
1 - Деструктуризация плоского объекта с параметрами по умолчанию
Разрушить этот объект легко:
let obj = {
foo: 'Foo',
bar: 'Bar'
};
С {foo = 'Foo', bar = 'Bar'} = {}
в сигнатуре функции объект будет создан, если при вызове функции не будет передан аргумент. Если объект передан, но некоторые ссылочные свойства имеют значение undefined
, они будут заменены значениями по умолчанию. Этот код работает нормально:
function fn1({foo = 'Foo', bar = 'Bar'} = {}) {
console.log(foo, bar);
}
// OK
fn1(); // Foo Bar
fn1({foo: 'Quux'}); // Quux Bar
fn1({bar: 'Quux'}); // Foo Quux
fn1({foo: 'Quux', bar: 'Quux'}); // Quux Quux
2 - Деструктуризация вложенных объектов с мелкими параметрами по умолчанию
Разрушить этот объект сложнее:
let obj = {
foo: 'Foo',
bar: {
quux: 'Quux',
corge: 'Corge'
}
};
{foo = 'Foo', bar = 'Bar'} = {}
больше не подходит, но теперь мы можем использовать {foo = 'Foo', bar = {quux: 'Quux', corge: 'Corge'}} = {}
в сигнатуре функции. Опять же, если при вызове функции не задан аргумент, создается объект и извлекаются основные свойства (foo
и bar
). Если объект передан, только неопределенные свойства (foo
или bar
) будут деструктурированы со значениями по умолчанию.
Проблема в том, что свойства объекта bar
(quux
и corge
) не являются частью "деструктуризации верхнего уровня". Это означает, что quux
или corge
будут равны undefined
, если они не установлены явно при передаче bar
в качестве аргумента:
function fn2({foo = 'Foo', bar = {quux: 'Quux', corge: 'Corge'}} = {}) {
console.log(foo, bar.quux, bar.corge);
}
// OK
fn2(); // Foo Quux Corge
fn2({foo: 'Quux'}); // Quux Quux Corge
// Oops!
fn2({bar: {quux: 'Baz'}}); // Foo Baz undefined
fn2({foo: 'Quux', bar: {corge: 'Baz'}}); // Quux undefined Baz
3 - Деструктуризация вложенных объектов с глубокими параметрами по умолчанию
Я хотел бы установить параметры по умолчанию на всех уровнях иерархии объектов, чтобы использовать своего рода «каскадную деструктуризацию». Я пробовал это, но это не работает:
function fn3({foo = 'Foo', bar = ({quux = 'Quux', corge = 'Corge'} = {})} = {}) {
console.log(foo, bar.quux, bar.corge);
}
// Oops!
fn3(); // Foo undefined undefined
fn3({foo: 'Quux'}); // Quux undefined undefined
fn3({bar: {quux: 'Baz'}}); // Foo Baz undefined
fn3({foo: 'Quux', bar: {corge: 'Baz'}}); // Quux undefined Baz
Знаете ли вы, разрешена ли такая функция в ES6. Если да, то как я могу это реализовать?