web-dev-qa-db-ja.com

オブジェクトの割り当てを破壊するための変数を事前に宣言できますか?

背景

配列を使用して代入を構造化解除しようとしたときに、変数を事前に宣言することができました。

let a, b, c;
let arr = [1, 2, 3, 4, 5];
[a, b, c] = arr;

console.log(a) // logs 1
console.log(b) // logs 2
console.log(c) // logs 3

これは、Babelコンパイラを問題なく通過しました。

しかし、オブジェクトで同じことをしようとすると、エラーが発生しました

let a, b, c
let obj = {cat: 'meow', dog: 'woof', mouse: 'squeak'};
{cat: a, dog: b, mouse: c} = obj;

console.log(a) // I want this to log 'meow'
console.log(b) // I want this to log 'woof'
console.log(c) // I want this to log 'squeak'

質問

これはES6またはバベルの癖/問題ですか? ES6で意図的なものである場合、配列の処理方法との違いは何ですか?

varletに置き換えることは、変数を事前に宣言する必要がないことと、letをインラインで持つことが有効であることを理解しています(そして、一般的には)。 「そのようにしないでください」という回答ではなく、実装間の違いについて知りたいのですが。

35
Lucy Bain

オブジェクトを破壊するとき、

  1. オブジェクトのキーと同じ変数名を使用する必要があります。そうして初めて、1対1の対応が得られ、値が適切に分解されます。

  2. 宣言ステートメントを使用しない場合は、割り当て全体を括弧で囲む必要があります。そうしないと、左側の式のオブジェクトリテラルがブロックと見なされ、構文エラーが発生します。


だからあなたの修正されたコードはこのようになります

'use strict';
let cat, dog, mouse;
let obj = {cat: 'meow', dog: 'woof', mouse: 'squeak'};
({cat, dog, mouse} = obj);     // Note the `()` around

これは

'use strict';
let obj = {cat: 'meow', dog: 'woof', mouse: 'squeak'};
let {cat, dog, mouse} = obj;
81
thefourtheye