【JavaScript】分割代入を誤解していたこと

JavaScript

JavaScriptの分割代入という記法について誤解していた部分のメモです。

分割代入は配列とオブジェクトでは挙動が異なる。ということを最近知りました。

配列は順序が一致
オブジェクトは名前が一致
することで値がとれる。

これだけだとよくわからないと思うんですが、似たような形式で書くのに、配列とオブジェクトで違う動きをするっていうのが混乱の元でした。

そもそも分割代入とはどのような記法なのか、から丁寧に見ていきます。

分割代入とは?

JavaScriptの分割代入(Destructuring Assignment) とは、配列やオブジェクトから特定の値を取り出し、変数に代入する構文です。

const user = { name: "Alice", age: 25 };

const { name, age } = user;

console.log(name); // "Alice"
console.log(age);  // 25

上の例だと、userのAliceのname, ageというオブジェクトのプロパティを、name, ageという名前の個別の変数として取り出せるようになります。

通常の変数代入と比べて、コードを簡潔に書けるため、可読性が向上します。

変数名をオブジェクトのプロパティとは違う名前にすることもできます。

const user = { name: "Bob", age: 30 };

const { name: userName, age: userAge } = user;

console.log(userName); // "Bob"
console.log(userAge);  // 30

{ name: userName, age: userAge }ここで

userオブジェクトの name プロパティの値 “Bob” を、新しい変数userNameに代入する。
userオブジェクトの age プロパティの値 30 を、新しい変数userAgeに代入する。

ということを行っています。

あとは const { name, age = 20 } = user; として値を入れておくことで、もともとのオブジェクトにageプロパティがなくても、デフォルト値として適用できます。

関数の引数に使うこともでき、Reactなどで多用されています。Reactをやると嫌でもこの記法に慣れていくと思います。function greeting({ name, age }) {…}という感じ。

配列とオブジェクトでの分割代入の挙動の違い

今までオブジェクトをメインに見てたんですが、配列でも分割代入が使えます。ただ代入する変数の使い方が違うというか、どの変数にどの値を入れるかのルールが、配列とオブジェクトで違います。

これらを知らずに使っていたので、なんか書き方でルールが違う人がいるなぁ…とか誤解してました。配列とオブジェクトではそもそも分割代入の書き方が違う、と思った方が早かったです。

配列での分割代入

//配列での分割代入

const array = [1, 2, 3];

const [first, second, third] = array;

console.log(first, second, third);//1 2 3

const [one, three, two] = array;

console.log(three);//2
  • 配列での分割代入は、インデックス(順番) に基づいて値を取り出しています。
  • 変数名は好きにつけていい!

配列の場合は順番が一致しているかどうかが大事で、値が入ってる順番と変数の順番が同じところにその値が入るので、one, three, twoと変数を入れても二番目のthreeのところには元の配列でも二番目の2が入っています。

配列にはプロパティ名みたいに名前はもともとないので、自由につけられます。

名前なんかどうでもいいんですよ。とにかく順番が大事で、書いてある順番が同じものがペアになっていく感じです。

オブジェクトでの分割代入

//オブジェクトでの分割代入

const object = { name: "neko", age: 5 };

const { age, name } = object;

console.log( name, age );//neko 5

次はもう一度オブジェクトでの分割代入に戻るんですが、上記の通り、

{ name: “neko”, age: 5 }; こういう順番を

const { age, name } 反対にして分割代入

しても、入る値が反対になるわけではありません。

オブジェクトでは名前が一致していればその値がとれるので、順番を逆にしてもそのプロパティ名が一致している値が取得できます。

オブジェクトの場合は名前が大事です。順番なんかどうでもいいです。配列のときと反対ですね。

※上でもかいていますが、オブジェクトの場合はプロパティ名と違う変数名に格納することもできますが、そのときもきちんとプロパティ名●●には変数◆◆を対応させると定義しなければいけません。

まとめ

配列とオブジェクトの分割代入の挙動の違いを表にまとめました。

分割対象取り出し基準順番の影響変数名の変更
配列インデックス影響ありできない
オブジェクトプロパティ名影響なしできる

👉 配列は「順番」、オブジェクトは「キー」が重要!

同じ書き方だと思ってると混乱するので注意したいです。