`var {…} =…`ステートメントの中括弧は何をしますか?


117

これがMozilla固有のJS構文かどうかはわかりませんが、たとえばアドオンSDKのドキュメントで、このように変数が宣言されていることがよくありました。

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

およびさまざまなクロムJavascript(letステートメントがの代わりに使用されていますvar)、

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

非常に混乱しましたが、MDNでも、両方の構文に関するドキュメントを見つけることができません。


@Blender symbolhound.comでこの構造をどのように検索しますか?
trusktr 2013

1
@trusktr:Aは、少し遅れ: symbolhound.com/...
ブレンダー

短い答えはこちらです:stackoverflow.com/a/45909752/203704
クリフホール

私は基本的な分解で大丈夫です。ただし、この例では、別のプロパティ名にも値を割り当てているため、その構文は非常に混乱します。これはオブジェクト作成構文と反対であり、さらに混乱を招きます。
Sol

回答:


72

どちらもJavaScript 1.7の機能です。最初のものはブロックレベルの変数です

let変数を宣言して、そのスコープを、それが使用されているブロック、ステートメント、または式に制限できます。これはvar、変数をグローバルに、またはブロックのスコープに関係なく関数全体に対してローカルに定義するキーワードとは異なります。

2つ目は、破壊と呼ばれます。

構造化代入により、配列およびオブジェクトリテラルの構造を反映する構文を使用して、配列またはオブジェクトからデータを抽出できます。
...
構造化代入で実行できる特に便利なことの1つは、構造全体を1つのステートメントで読み取ることです。

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;

2番目のコードチャンクは次のように書き換えることができます。

let Cc = Components.classes;
let Ci = Components.interfaces;
let Cr = Components.results;
let Cu = Components.utils;

2
私の実験から、var { Hotkey }はに相当するように見えvar { Hotkey: Hotkey }ます。ドキュメントを見つけていただき、ありがとうございます。
timdream 2013年

@timdream:そのような感じがしましたが、それとどう違うのvar Hotkey = require(...).Hotkeyですか?それともキーストロークを保存するだけですか?
Blender 2013年

そのように見えます:-/(へへへ、これらの怠惰なプログラマー...)
timdream

2
さらに、このような珍しい構文を使用すると、すべてがよりわかりにくくなります。
trusktr 2013

2つ目は「オブジェクトの破壊」
です。developer.mozilla.org/ en

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 2013年

@Blender-オブジェクト分解の例を提供します。オブジェクトの配列の値全体のループを見てください。
Aadit M Shah 2013

var {a, b, c} = ascii;構文を意味しました。
Blender 2013年

最後の例は、通常、コロンの左側にあるものが割り当てられているため、奇妙です。
カーティス

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(p); // 42 console.log(q); // true

//新しい変数名を割り当てるvar {p:foo、q:bar} = o;

console.log(foo); // 42 console.log(bar); // true


0

letMDNに関する声明のドキュメントがあります:https : //developer.mozilla.org/en-US/docs/JavaScript/Reference/Statements/let

letvar宣言された変数のスコープを制限するという点で似ています。これにより、if(){}ブロック(またはその他のブロック)内で変数を宣言し、その変数をそのブロック内でのみ「可視」にすることができます(JavaScriptは、これまで、関数スコープを持ち、他のほとんどの言語のようにブロックスコープを持ちません)。したがって、これletは基本的に、多くの人が問題を抱えている問題に対する「修正」です。tihsはJavaScript 1.7の機能であることに注意してください。

で何も見つかりませんでした{Foo}


申し訳ありませんが、両方について質問していると思いました...私のgoogle-fuは次の点で失敗しました{Foo}:/
JanHančičMar

私もそうです: - / Googleはしないインデックス{}
timdream 2013年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.