Можно ли установить значение параметра по умолчанию для параметра покоя
ES6 представляет набор удобных "синтаксических сахара". Среди них - возможности параметров по умолчанию функций JavaScript, а также остальные параметры. Я обнаружил, что моя консоль (или devTools) жалуется (то есть выдает ошибку) всякий раз, когда пытается установить значение параметра по умолчанию для параметра rest. Я нашел удивительно мало ссылок на этот конкретный вопрос в другом месте, и мне интересно, если 1.) возможно ли это сделать и 2.) почему нет (при условии, что это невозможно).
В качестве примера я придумал тривиальный (но, надеюсь, все еще целеустремленный) пример. В этой первой итерации функции я построил функцию так, чтобы она работала (то есть, не давая параметру rest значение по умолчанию).
const describePerson = (name, ...traits) => `Hi, ${name}! You are ${traits.join(', ')}`;
describePerson('John Doe', 'the prototypical placeholder person');
// => "Hi, John Doe! You are the prototypical placeholder person"
Однако теперь по умолчанию:
const describePerson = (name, ...traits = ['a nondescript individual']) => `Hi, ${name}! You are ${traits.join(', ')}`;
describePerson('John Doe');
// => Uncaught SyntaxError: Unexpected token =
Любая помощь с благодарностью.
3 ответа
Нет, остальные параметры не могут иметь инициализатор по умолчанию. Это не разрешено грамматикой, потому что инициализатор никогда не будет запущен - параметру всегда присваивается значение массива (но, возможно, пустое).
То, что вы хотите сделать, может быть достигнуто либо
function describePerson(name, ...traits) {
if (traits.length == 0) traits[0] = 'a nondescript individual';
return `Hi, ${name}! You are ${traits.join(', ')}`;
}
или же
function describePerson(name, firstTrait = 'a nondescript individual', ...traits) {
traits.unshift(firstTrait);
return `Hi, ${name}! You are ${traits.join(', ')}`;
}
// the same thing with spread syntax:
const describePerson = (name, firstTrait = 'a nondescript individual', ...otherTraits) =>
`Hi, ${name}! You are ${[firstTrait, ...otherTraits].join(', ')}`
Просто пришло добавить более чистую систему настроек по умолчанию:
const describePerson = (name, ...traits) => {
traits = Object.assign(['x', 'y'], traits);
return `Hi, ${name}, you are ${traits.join(', ')}`;
}
describePerson('z'); // you are z, y
describePerson('a', 'b', 'c'); // you are a, b, c
describePerson(); // you are x, y
Это работает, потому что массивы - это объекты, индексы которых являются ключами, а Object.assign
заменяет ключи первого объекта, присутствующего во втором, значениями второго.
Если у второго нет индекса 1, он не будет перезаписан, но если у него есть индекс 0, индекс 0 первого массива будет перезаписан вторым, что вы ожидаете при использовании по умолчанию
Обратите внимание, что распространение массивов - это не то же самое, что распространение объектов, поэтому [....['x', 'y'], ...traits]
не будет перезаписывать индексы
Есть решение:
const describePerson = (name, ...[
first = 'a nondescript individual',
...traits
]) => `Hi, ${name}! You are ${[first, ...traits].join(', ')}`;