Что делают фигурные скобки в операторах `var {…} =…`?

117

Не уверен, что это синтаксис JS, специфичный для Mozilla, но я часто обнаруживал, что переменные объявляются таким образом, например, в дополнительных документах SDK :

var { Hotkey } = require("sdk/hotkeys");

и в различных Chrome Javascript ( letвместо этого используется оператор var),

let { classes: Cc, interfaces: Ci, results: Cr, utils: Cu }  = Components;

Меня это очень сбивает с толку, но я не могу найти никакой документации по обоим синтаксисам даже по MDN .

timdream
источник
@Blender Как бы вы искали эту структуру на symbolhound.com?
trusktr 02
1
@trusktr: Немного поздно: symbolhound.com/…
Blender
Краткий ответ здесь: stackoverflow.com/a/45909752/203704
Cliff Hall,
Я хорошо разбираюсь в базовой деконструкции. Однако в этом примере мы также присваиваем значение другому имени свойства, и этот синтаксис очень сбивает с толку. Он противоположен синтаксису создания объекта и добавляет еще больше путаницы.
Соль

Ответы:

72

Это обе функции JavaScript 1.7. Первый - это переменные уровня блока :

letпозволяет объявлять переменные, ограничивая его область действия блоком, оператором или выражением, в котором он используется. Это отличается от varключевого слова, которое определяет переменную глобально или локально для всей функции, независимо от области действия блока.

Второй называется деструктуризацией :

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

Для тех, кто знаком с Python, он похож на этот синтаксис:

>>> a, (b, c) = (1, (2, 3))
>>> a, b, c
(1, 2, 3)

Первый фрагмент кода является сокращением для:

var {Hotkey: Hotkey} = require("sdk/hotkeys");
// Or
var Hotkey = require("sdk/hotkeys").Hotkey;

Вы можете переписать второй фрагмент кода как:

let Cc = Components.classes;
let Ci = Components.interfaces;
let Cr = Components.results;
let Cu = Components.utils;
смеситель
источник
2
Судя по моему эксперименту, похоже, var { Hotkey }эквивалентно var { Hotkey: Hotkey }. Спасибо, что нашли документацию!
timdream 08
@timdream: У меня было ощущение, что это было что-то в этом роде, но чем это отличается от этого var Hotkey = require(...).Hotkey? Или это просто экономия нажатий клавиш?
Blender
выглядит так: - / (хе-хе, эти ленивые программисты ...)
timdream
2
Кроме того, использование такого необычного синтаксиса делает все более загадочным.
trusktr 02
Второй «DESTRUCTURING Объект», refere к developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
IcyBrk
80

Вы смотрите на деструктурирующее задание. Это форма сопоставления с образцом, как в Haskell.

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

Например:

var ascii = {
    a: 97,
    b: 98,
    c: 99
};

var {a, b, c} = ascii;

Приведенный выше код эквивалентен:

var ascii = {
    a: 97,
    b: 98,
    c: 99
};

var a = ascii.a;
var b = ascii.b;
var c = ascii.c;

Аналогично для массивов:

var ascii = [97, 98, 99];

var [a, b, c] = ascii;

Это эквивалентно:

var ascii = [97, 98, 99];

var a = ascii[0];
var b = ascii[1];
var c = ascii[2];

Вы также можете извлечь и переименовать свойство объекта следующим образом:

var ascii = {
    a: 97,
    b: 98,
    c: 99
};

var {a: A, b: B, c: C} = ascii;

Это эквивалентно:

var ascii = {
    a: 97,
    b: 98,
    c: 99
};

var A = ascii.a;
var B = ascii.b;
var C = ascii.c;

Это все, что нужно сделать.

Аадит М Шах
источник
12
+1 за примеры деструктуризации объектов, они действительно полезны. В примерах MDN показывают только массив деструктурирующие.
Blender
@Blender - они предоставляют примеры деструктуризации объектов. Посмотрите на Цикл по значениям в массиве объектов .
Aadit M Shah
Я имел ввиду var {a, b, c} = ascii;синтаксис.
Blender
Последний пример действительно странный, потому что обычно назначается то, что слева от двоеточия.
Curtis
1

Это разрушающее задание в Javascript и является частью стандарта ES2015. Он распаковывает или извлекает значения из массивов или свойств из объектов в отдельные переменные. Например: деструктуризация массива

var foo = ["one", "two", "three"];
//without destructuring
var one = foo[0];
var two = foo[1];
var three = foo[2];

// с деструктуризацией var [one, two, three] = foo

Например: деструктуризация объекта

var o = {p: 42, q: true}; var {p, q} = o;

console.log (р); // 42 console.log (q); // правда

// Присваиваем новые имена переменных var {p: foo, q: bar} = o;

console.log (Foo); // 42 console.log (bar); // правда

Дикша Шарма
источник
0

Есть документация для letзаявления на MDN: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/let

letаналогичен varтем, что ограничивает объем объявленной переменной. Он позволяет вам объявлять переменную внутри if(){}блока (или какого-либо другого блока) и иметь эту переменную только «видимой» внутри этого блока (JavaScript до сих пор имеет область действия, а не область действия блока, как в большинстве других языков). Так что letэто в основном "исправление" того, с чем у многих возникают проблемы. Обратите внимание, что tihs - это функция JavaScript 1.7.

Ничего не нашел {Foo}.

Ян Ганчич
источник
Извините, я думал, вы спрашиваете об обоих ... Мой гугл-фу меня подводит, когда дело доходит до {Foo}: /
Ян Ганчич
Я тоже: - / Google не индексирует {и }.
timdream 08