JavaScript | 基礎構文:変数・定数 – 多重代入

JavaScript
スポンサーリンク

多重代入を一言でいうと

多重代入(たじゅうだいにゅう)は、
「1 行の代入文で、複数の変数にまとめて値を入れる書き方」 のことです。

a にも b にも 0 を入れたい
x と y に、それぞれ別の値を一気にセットしたい

こういうときに、1 行ずつ書くのではなく、
「1 つの代入式で複数の変数に値を入れる」 ための書き方がいくつかあります。

ここが重要です。
JavaScript での多重代入には

  1. a = b = c = 0; のような「代入の連結」
  2. let [x, y] = [1, 2]; のような「分割代入(配列・オブジェクト)」

の 2 つのパターンがあり、
それぞれ意味と注意点が違うので、分けて理解する必要があります。


パターン1:代入の連結(a = b = c = 0 の形)

何が起きているのかを分解してみる

まず、よく見る形からいきます。

let a, b, c;
a = b = c = 0;
console.log(a, b, c); // 0 0 0
JavaScript

一見、「3つまとめて 0 を入れている」ように見えますが、
実際にはこういう順番で評価されています。

  1. c = 0 が実行される(c に 0 が入る)
  2. b = (c = 0 の結果)b = 0
  3. a = (b = 0 の結果)a = 0

つまり、「右から左に」代入が流れていきます。

代入式は、「代入した値自体を返す」性質があるので、
(c = 0) の結果が 0、その 0 を b = に渡し、その結果がまた 0…
というふうに伝わっていき、最終的に a, b, c が全部 0 になります。

宣言と同時に書くパターン

宣言と多重代入を一緒に書くこともあります。

let a = 0, b = 0, c = 0;
JavaScript

これはイメージとしては、

let a = 0;
let b = 0;
let c = 0;
JavaScript

と同じです。
この形は「単に 1 行に並べているだけ」で、先ほどの a = b = c = 0 とは少し意味が違います。

注意点:すでにある変数を巻き込んでしまわないか

次のようなコードを見てください。

let a = 1;
let b;

b = a = 5;

console.log(a, b); // 5 5
JavaScript

b = a = 5; は、

  1. a = 5
  2. b = (a = 5 の結果 5)

という流れなので、
ab も 5 になります。

「b だけ変えたいつもりだったのに、a も変わってしまった」
ということが起き得ます。

ここが重要です。
「代入の連結(a = b = c = 0)」は、右側の変数も一緒に書き換えてしまう。
“どの変数がどこで変わっているか” が分かりにくくなりやすいので、乱用はおすすめしません。
“単に同じ初期値を入れたい” だけなら、let a = 0, b = 0; のほうが安全です。


パターン2:分割代入(配列・オブジェクトを使う多重代入)

ここからが「モダンな多重代入」の本番です。
配列やオブジェクトから、複数の値を一気に取り出して変数に代入する書き方 です。

配列の分割代入:左と右の「位置」を対応させる

基本形はこれです。

let [x, y] = [1, 2];

console.log(x); // 1
console.log(y); // 2
JavaScript

左側の [x, y] は「受け取る側の変数リスト」、
右側の [1, 2] は「値の配列」です。

位置で対応します。

  • 1番目 → x
  • 2番目 → y

という対応です。

もう少し見てみましょう。

let arr = [10, 20, 30];

let [a, b, c] = arr;
console.log(a, b, c); // 10 20 30
JavaScript

いらない要素は飛ばせる(カンマで穴をあける)

「2番目だけ欲しい」というときもあります。

let arr = [10, 20, 30];

let [, second] = arr;

console.log(second); // 20
JavaScript

最初のカンマの位置が「1番目の要素」を表し、
そこに変数名を書かないことで「捨てる」ことができます。

swap(値の入れ替え)を 1 行で書ける

分割代入の代表的な便利テクが「変数の中身の入れ替え(swap)」です。

普通に書くとこうです。

let a = 1;
let b = 2;

let temp = a;
a = b;
b = temp;

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

これを分割代入を使うと、1 行で書けます。

let a = 1;
let b = 2;

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

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

右側の [b, a] は、代入前の ba を並び替えた配列です。
それを [a, b] に分割代入することで、
一時的な変数なしで中身の入れ替えができます。

ここが重要です。
配列の分割代入は、「位置順に複数の値を変数に割り振る」ための多重代入。
特に、配列から複数の値を取り出すときや、値の入れ替え(swap)で非常に役に立ちます。


オブジェクトの分割代入:名前で対応させる多重代入

基本形:プロパティ名と変数名を一致させる

オブジェクトからも、多重代入ができます。

const user = {
  name: "Taro",
  age: 20,
};

const { name, age } = user;

console.log(name); // "Taro"
console.log(age);  // 20
JavaScript

ここでは、

  • { name, age } が「受け取る側」
  • user が「元のオブジェクト」

です。

user.namename に、user.ageage に、
「同じ名前で」取り出して代入してくれます。

変数名を変えることもできる

「オブジェクトのプロパティ名」と「変数名」を変えたい場合もあります。

const user = {
  name: "Taro",
  age: 20,
};

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

console.log(userName); // "Taro"
console.log(userAge);  // 20
JavaScript

name: userName は、

user.nameuserName という変数に代入」

という意味です。

引数での多重代入(よく使うパターン)

関数の引数でも分割代入がよく使われます。

function showUser({ name, age }) {
  console.log(`名前: ${name}, 年齢: ${age}`);
}

const user = { name: "Taro", age: 20 };

showUser(user);
JavaScript

この場合、

  • 引数 user の中から nameage を取り出して
  • そのままローカル変数 name, age として使える

という形になります。

ここが重要です。
オブジェクトの分割代入は、「名前をキーにして複数の値を一気に取り出す」多重代入。
オブジェクトのプロパティが増えても、必要なものだけを選んで取り出せるので、コードが読みやすくなります。


多重代入で「やりすぎる」と読みにくくなる例と注意点

代入の連結をやりすぎる例

次のようなコードは、一見 “ワザが効いていて” かっこよく見えるかもしれませんが、
読みやすさとしてはあまりよくありません。

let a, b, c;
a = b = c = doSomething();
JavaScript

何が問題かというと、

  • doSomething() の結果が 3 つの変数に全部入る
  • bc はどこで初期化されたか一目で分かりにくい
  • doSomething() に副作用(中で何かを変える処理)があると、さらにややこしい

という点です。

安全さと読みやすさを重視するなら、
素直にこう書いたほうが良いことが多いです。

const result = doSomething();
let a = result;
let b = result;
let c = result;
JavaScript

分割代入も「1 行に詰め込みすぎない」

分割代入も、便利だからといって全部詰め込むと読みにくくなります。

例えば:

const { name, age, address: { city, zip }, options: { theme = "light" } } = user;
JavaScript

一応正しいのですが、
初心者にとっては「何をしているのか一瞬で理解する」のは難しいです。

分けて書いたほうが読みやすい場面も多いです。

const { name, age, address, options } = user;
const { city, zip } = address;
const { theme = "light" } = options || {};
JavaScript

ここが重要です。
多重代入(特に分割代入)は便利だけど、「読みやすさ」を犠牲にしてまで 1 行に詰め込む必要はない。
“自分や他人が 3 秒で理解できるか” を基準に、分けるところは分けるのが上手な使い方です。


初心者としての「多重代入」の押さえどころ

最後に、最初のうちに押さえておくべきポイントだけを整理します。

多重代入には大きく 2 種類ある。

  1. a = b = c = 0 のように「代入を連結する」形
  2. let [x, y] = [1, 2];const { name, age } = user; のように「分割代入」を使う形

a = b = c = 0 は、「右から左へ」代入が流れる。
巻き込まれて変わってほしくない変数まで書き換えてしまう危険があるので、乱用はしない。

配列の分割代入:let [x, y] = [1, 2];
位置(1番目、2番目…)で対応し、複数の値を一気に取り出したり、[a, b] = [b, a]; のように値を入れ替えたりできる。

オブジェクトの分割代入:const { name, age } = user;
プロパティ名をキーにして複数の値を取り出せる。必要なものだけ選べるので、関数引数でもよく使う。

ここが重要です。
多重代入は「便利なショートカット」ですが、魔法ではありません。
“どの値が、どの変数に、どんな順番で入っているか” を頭の中で追える範囲で使うこと。
まずは配列とオブジェクトの分割代入から慣れていくのがおすすめです。

練習としては、

  1. 配列 [1, 2, 3] から a, b, c を分割代入で取り出す
  2. ab の値を [a, b] = [b, a]; で入れ替えてみる
  3. user = { name: "Taro", age: 20 } から name だけを { name } で取り出す

この 3 ステップを自分で書いて実行してみると、
多重代入のイメージがかなりクリアになってくるはずです。

タイトルとURLをコピーしました