Несколько трюков с использованием деструктурирования

ECMAScript 6

Содержание этой статьи в основном взято из статьи Николаса С. Закаса «Понимание ECMAScript 6».

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

Value Swapping

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

// Swapping variables in ECMAScript 5
let a = 1,
    b = 2,
    tmp;

tmp = a;
a = b;
b = tmp;

console.log(a);     // 2
console.log(b);     // 1

В ECMAScript 6 присваивание деструктуризации массива можно использовать для замены значений двух переменных.

// Swapping variables in ECMAScript 6
let a = 1,
    b = 2;

[ a, b ] = [ b, a ];

console.log(a);     // 2
console.log(b);     // 1

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

Use Rest Items to Create a Clone

В ES5 мы часто используемconcat()Как простой способ клонировать массив.concat()Метод предназначен для объединения двух массивов. При вызове без аргументов он возвращает клонированную версию текущего массива.

// cloning an array in ECMAScript 5
var colors = [ "red", "green", "blue" ];
var clonedColors = colors.concat();

console.log(clonedColors);      //"[red,green,blue]"

В ES6 это требование можно выполнить с помощью остальных элементов.

// cloning an array in ECMAScript 6
let colors = [ "red", "green", "blue" ];
let [ ...clonedColors ] = colors;

console.log(clonedColors);      //"[red,green,blue]"

По сравнению с методом concat() использование деструктурирования может более четко выразить намерение разработчика и повысить читабельность кода.

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

Destructured Parameters

Деструктуризация также имеет очень полезный случай, который используется в параметрах функции.

Мы иногда сталкиваемся с такой ситуацией: функция JS принимает некоторые необязательные параметры в дополнение к нескольким фиксированным параметрам. Обычно мы могли бы использоватьoptionОбъект с необязательными параметрами в качестве свойств этого объекта.

// properties on options represent additional parameters
function setCookie(name, value, options) {

    options = options || {};

    let secure = options.secure,
        path = options.path,
        domain = options.domain,
        expires = options.expires;

    // code to set the cookie
}

// third argument maps to options
setCookie("type", "js", {
    secure: true,
    expires: 60000
});

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

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

function setCookie(name, value, { secure, path, domain, expires }) {

    // code to set the cookie
}

setCookie("type", "js", {
    secure: true,
    expires: 60000
});

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

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

Destructured Parameters are Required

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

// Error!
setCookie("type", "js");

Причина ошибки: параметр деструктурирования на самом деле является сокращением для объявления деструктурирования, на самом деле JS-движок сделает следующее для приведенного выше кода:

function setCookie(name, value, options) {

    let { secure, path, domain, expires } = options;

    // code to set the cookie
}

При деструктурировании присваивания, если значение выражения в правой части оператора присваивания равноnullилиundefinedсообщит об ошибке, потому что вы не можетеnullилиundefinedЧитать свойства в .

следовательноsetCookie()При вызове функции будет сообщено об ошибке, если не будет передан третий параметр.

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

function setCookie(name, value, { secure, path, domain, expires } = {}) {

    // ...
}

Default Values for Destructured Parameters

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

function setCookie(name, value,
    {
        secure = false,
        path = "/",
        domain = "example.com",
        expires = new Date(Date.now() + 360000000)
    } = {}
) {

    // ...
}

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

Рекомендуется использовать параметры деструктурирования вместо ваших «опционных» объектов в объявлениях функций. С одной стороны, он может четко выражать параметры, требуемые функцией, и в то же время он может предоставлять значения по умолчанию для необязательных параметров относительно удобным способом.

добавить другое использование

function test(...args) {
  console.log('====', args); //打印出来的args是数组[1, 2, 3]
}

test(1, 2, 3)

Это можно использовать в сценариях, где используется apply, например:

function bind(fn) {
  return function (...args) {
    fn.apply(this, args)
  }
}

Если вам не нужно деконструировать, вам нужно обработать аргументы в массив

function bind(fn) {
  return function () {
    var args = [].concat(arguments)
    fn.apply(this, args)
  }
}