Хорошо, я знаю, что это ОЧЕНЬ специфическая ситуация, и это вряд ли произойдет, но кто знает? ¯ \ _ (ツ) _ / ¯

ько что увидел фрагмент кода в MDN о деструктурировании остальных параметров:

function f(...[a, b, c]) {
  return a + b + c;
}

f(1)          // NaN (b and c are undefined)
f(1, 2, 3)    // 6
f(1, 2, 3, 4) // 6 (the fourth parameter is not destructured)

фрагмент кода находится на этой странице:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters

Хотя общий вариант использования параметров отдыха мне очень понятен (function foo(...params){/*code*/}Я не мог думать о реальном случае использования для использования параметров покоя, как в этом фрагменте кода. Вместо этого я думаю, что в этом случае я должен просто использовать общее определение функции:

function f(a, b, c) {
  return a + b + c;
}

f(1)          // NaN (b and c are undefined)
f(1, 2, 3)    // 6
f(1, 2, 3, 4) // 6 (the fourth parameter is not defined)
 Amy29 дек. 2017 г., 18:33
Это может быть полезно, не уверен:gist.github.com/yang-wei/3d35e8692dbc6cc0f98d
 Jonas Wilms29 дек. 2017 г., 18:40
...[a,,c] однако, это все еще не очень полезно
 Amy29 дек. 2017 г., 18:49
@ AndréMarcondesTeixeira да, я не был уверен. это хорошо, хотя
 Olian0429 дек. 2017 г., 18:43
Я думаю, что это большеyou can скорее, чемyou should вид сделки .. :)
 André Marcondes Teixeira29 дек. 2017 г., 18:43
Спасибо за ссылку Эми, но эта суть не говорит об этом конкретном сценарии :)

Ответы на вопрос(5)

На самом деле... Оператор двумя способами. Это называетсяотдых а такжераспространение в зависимости от вашего варианта использования. Они оба очень мощные операторы, особенно для функциональных подходов. Вы всегда можете использовать оператор спреда, как,

var a = [1,2,3],
    b = [4,5,6];
a.push(...b);

который дастa быть[1,2,3,4,5,6] все вместе. В этот момент можно сказать, что.concat() мог бы сделать то же самое. Да, Concat имеет встроенную функциональность распространения, ноa.concat(b) не повлияетa, Я просто создаю и возвращает новый массив. На самом деле в правильных функциональных языков леченияa как неизменный объект хорош ради чистоты. Все же JS - странный язык. Он считается функциональным, но в то же время глубоко охватывает ссылочные типы. Короче говоря, если вы хотите сохранить ссылки наa неповрежденный, мутируя, тогда вы не можете использоватьa.concat(b) ноa.push(...b), Здесь я должен упомянуть, что.push() не идеально разработан, потому что он возвращает глупое свойство длины, котороесовершенно бесполезно, Должен был вернутьсяa, Таким образом, я в конечном итоге с помощью оператора запятой, как(a.push(...b),a) в большинстве случаев.

Хорошо, кроме простых случаев использования, вы можете растянуть... далее для немного более сложных, но классно выглядящих реализаций. Например, вы можете сделать паттерн Хаскелеска, соответствующий разделению головы и хвоста массива, и соответственно выполнить рекурсию.

Вот полезный случай операторов распространения и отдыха, работающих рука об руку, чтобы сгладить произвольный вложенный массив.

var flat = (x,...xs) => x ? [...Array.isArray(x) ? flat(...x) : [x], ...flat(...xs)] : [];

var na = [[1,2],[3,[4,5]],[6,7,[[[8],9]]],10];
    fa = flat(na);
console.log(fa);

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

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

const tail = function([, ...xs]) { return xs; } tail([1,2]); // [2]

const head = ([a]) => a
head([1,2,3,4]) // 1

function getCustomer(id) {
    return fetch(`http://myapi.com/customer/${id}`);
}

и скажем, у меня есть такой ответ:

{
    "customer": {
        "id": 1234,
        "name": "John Doe",
        "latestBadges": [
            "Platinum Customer",
            "100 Buys",
            "Reviewer"
        ]
    }
}

В более традиционном подходе я мог бы написать функцию для отображения последних 3 значков, например:

function showLatestBadges(a, b, c) {
    console.log(a, b, c);
}

и чтобы использовать эту функцию, мне нужно:

getCustomer(1234).then((customer) => {
    showLatestBadges(
        customer.latestBadges[0],
        customer.latestBadges[1],
        customer.latestBadges[2]
    );
});

С этим новым оператором распространения я мог бы сделать это вместо этого:

getCustomer(1234).then((customer) => {
    showLatestBadges(...customer.latestBadges);
});

Таким образом, использование оператора распространения в определении функции может показаться немного бесполезным. Но на самом деле это МОЖЕТ быть полезным в ОЧЕНЬ конкретной ситуации:

Допустим, у нас есть устаревшая система, и скажем, что призыв кshowLatestBadges Функция создается в сотнях мест без использования оператора распространения, как в старые времена. Давайте также предположим, что мы используем инструмент linting, который предотвращает неиспользуемые переменные, и давайте также предположим, что мы запускаем процесс сборки, который заботится о результатах linting, и если linting говорит, что что-то не так, сборка завершается неудачно. Давайте также предположим, что для какого-то странного бизнес-правила мы теперь должны показывать только первый и третий значки. Теперь, предполагая, что этот вызов функции выполняется в сотнях мест в унаследованной системе, и у нас не так много времени для реализации этого нового бизнес-правила, у нас нет времени на рефакторинг кода для ВСЕХ этих сотен вызовов. , Итак, теперь мы изменим функцию следующим образом:

function showLatestBadges(a, b, c) {
    console.log(a, c);
}

Но теперь у нас есть проблема: сборка не удалась из-за неиспользованногоb переменная, и мы должны доставить это изменение на ВЧЕРА !!! У нас нет времени на рефакторинг всех сотен обращений к этой функции, и мы не можем просто выполнить простой поиск и замену во всех точках, потому что у нас такой грязный код, повсюду есть ошибки и непредсказуемое поведение может случиться.

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

function showLatestBadges(...[a,,c]) {
    console.log(a, c);
}

Хорошо, я знаю, что это ОЧЕНЬ специфическая ситуация, и это вряд ли произойдет, но кто знает? ¯ \ _ (ツ) _ / ¯

function f(a, b, c) { … } это действительно правильный способ написать это. Единственная разница между этим и синтаксисом rest + destruuring заключается в том, что остальные параметры не увеличивают количество параметров, т.е.f.length == 0.

На самом деле нет хорошего варианта использования шаблона деструктуризации массива в качестве цели параметра rest. То, что синтаксис позволяет это, не означает, что это где-то полезно. Пример MDN, вероятно, должен был прояснить это.

Ваш ответ на вопрос