JavaScript で、知っているとちょっと便利な「分割代入」の話

  • 2019/5/27
  • JavaScript で、知っているとちょっと便利な「分割代入」の話 はコメントを受け付けていません。

今回は分割代入をやるよ!

2015 年に標準化された、 JavaScript の比較的新しい仕様として、
「分割代入」というものがあります。

覚えておくと割と便利なのですが、あまり使われていない気がするので、
今回はこの、ちょっと便利な分割代入をご紹介しましょう。

最初に、対応しているブラウザ確認

分割代入は新しめの仕様なので、各ブラウザが対応しているかどうかを確認してみましょう。
いつもの Can I use で調べてみると…

IE 以外の主要ブラウザでは対応されていますね!
最悪、IE でも使いたいんだけどって話になれば、そのあたり babel とか使えば
IE でも読めるようにうまく変換してくれるからいいですね。

分割代入!基本の使い方

配列

さて、分割代入の具体的な話に入っていきます。

分割代入は一言で言えば、
配列やオブジェクトを変数に代入するときに、それをバラして入れてくれるという機能です。

例えば、分割代入なしで書くと

const ary = [3, 5];

const a = ary[0];  // 3
const b = ary[1];  // 5

こんな感じの処理。
これは、まず ary 変数に [3, 5] の配列が代入されますよね。
(const は変数定義ですね)
で、配列の 0 番目、 1 番目をそれぞれ a, b の変数に代入している、という流れになります。
で、 a には 3 が、b には 5 が代入されますね。

これを分割代入を使って書くと…

const ary = [3, 5];

const [a, b] = ary;
// a = 3
// b = 5

なんと!定義側にも配列みたいな [a, b] が出てきましたね!
こんな感じで変数定義側に書くことで、代入する配列 ary にある、
位置が対応する値が a, b に直接入っていくのですね。

対応する形であればよいので、こんなこともできます。

const ary = [3, [6, 9]];

const [a, [b, c]] = ary;
// a = 3
// b = 6
// c = 9

入れ子になっている配列についても、うまいこと展開してやってくれます。

オブジェクト

この分割代入、オブジェクトでも同じように使うことができます。

const obj = {a: 3, b: 6};

const {a, b} = obj;
// a = 3
// b = 6

配列の場合は変数を書く場所を、配列の値の場所を合わせましたが、
オブジェクトの場合は、代入したいプロパティと名前を合わせます。

const obj = {a: 3, b: 6};

const {b, a} = obj;
// a = 3
// b = 6

つまり、こういうことをしたら、配列の場合は値が入れ替わって入ってしまいますが、
オブジェクトの場合は名前が一致しているところに値を入れるので、
先ほどと同じ結果となる、ということですね。

ちなみに、配列の方ではできないのですが、
オブジェクトのほうはデフォルト値の設定ができます。

const obj = {a: 3, b: 6};

const {a = 10, c = 10} = obj;
// a = 3
// c = 10 (c は obj のプロパティとして存在しないので、デフォルト値が使用される)

便利な使い方

正規表現での解析結果からの値の取り出し

JavaScript では正規表現にマッチした結果を配列として返してきてくれますよね。

const parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(’https://example.com/path’);
const [, protocol, host, path] = parsedURL;

parsedURL には [’https://example.com/path’, ’https’, ’example.com’, ’path’] か入ってきますから、
これらを一つずつ変数代入するよりは、こんな感じでひとまとめにしてしてしまった方がスマートですよね。

値の入れ替え

(最近ではあまりないですが)例えば、変数 a と b の値を入れ替えるときは

let swap = a;
let a = b;
let b = swap;

こんな感じで、仮置きの変数を用意して実施しますよね?

でも、今回の分割代入を使うと

[a, b] = [b, a]

それぞれの位置の値を代入してくれるので、こんな感じで一行で書いてしまうこともできるのですね!
そんなに使う頻度はないですが、覚えておくと面白いタイプの小ネタです。

関数の引数を展開する

正直今回これを書きたかったがためにこの記事を書いてるくらいな、
みんなに知ってもらいたい便利な書き方。

オブジェクトは

const {b, a} = obj;

みたいな感じで展開すると、同じ名前のプロパティを変数に展開してくれると書きましたが、
これは関数の引数のところで同じように使えて、

// 引数受け取りのところでオブジェクトを展開
const sum = function({a, b}) {
  return a + b;
}

const obj = {a: 3, b: 4};

sum(obj); // 7 が返ってくる

こんなことができます。

これの何が便利って、ライブラリとかを使ってると、
一つのオブジェクトにいろいろなプロパティが格納されて一つになっていることがよくありますが、

  • 関数を使う側はそのオブジェクトからプロパティを取り出さずそのまま渡せる
  • 関数側は、オブジェクト内の不必要なプロパティは触ることなく処理ができる

ということなんですね。

もし、まだ使ったことがなければ、
実際に使ってみてもらったら、その便利さに驚くこと間違いなしです。

反復処理の変数も展開する

関数の引数と同じように

const ary = [
  {name: ’hoge’, age: 10},
  {name: ’fuga’, age: 12},
];

for ({name} of ary) {
  console.log(name); // hoge fuga
}

こんな感じで使えば、変数を展開した状態でループの中で使えます。
…が、関数の引数ほどの便利性は無いかな…

変数名の変更

ここからは多分使わない、というか可読性が落ちるので使いどころを考えてもらう必要があるネタです。
私は一度も使ったことないですが、一応こんなこともできますよというお話。

const obj = {a: 3, b: 6};

const {a: anotherName} = obj;

console.log(anotherName); // 3

こんな感じで、元々のオブジェクト名の後ろに、コロンと別名を記載しておくことで、
別名の方を変数名として値を代入してくれます。

今回の例だと、元のプロパティ名である a の変数は作成されないのでご注意。

先ほどの関数の引数のところで展開する技と組み合わせると、
関数の中に、好きな名前で変数を作ることができます…
が、大抵プロパティ名で事足りるので、やっぱりほぼ使わないかな。

デフォルト関数

オブジェクトの分割代入ではデフォルト値を設定できるという話を最初の方にしました。

あのデフォルト値なのですが、本当は単純な値だけでなく、関数も指定できてしまうのです。

const obj = {a: 3, b: 6};

const def = function() {
  return 10;
}

const {c = def()} = obj;

console.log(c); // 10

できます。できますが…
こういう訳の分からないことをし始めると、黒魔術に入門してしまうのでやめましょう。

ちなみに、一応補足しておくと、
デフォルト値の設定時点で () をつけていますが、
今回の場合で言えば a プロパティを参照するなどの、デフォルト値が使用されない場合には
この関数は実行されません。

…ということは、プロパティが設定されているときのみ実行される関数なんかかけそうですね。

const obj = {a: 3, b: 6};

const {c = (() => console.log(’c は定義されてないよ!’))()} = obj;

読む人からしたら、えげつないのでやめてくださいね。

まとめ

分割代入の可能性を色々と感じていただけたかなと思います。

最後のはネタとしてしか使えないですが、
関数の引数で分割代入は本当に便利なので皆さん使ってみてくださいね!

Takato Ezaki

Takato Ezaki小中高の塾講師からエンジニア

投稿者プロフィール

福岡で Web 系のエンジニアをしています。

中高の理科教師免許を取り、起業に 2 年間トライした後エンジニアの道へ入りました。

化学反応の中では Belousov-Zhabotinsky 反応が大好きです。

この著者の最新の記事

関連記事

コメントは利用できません。

募集中!(o゜▽゜)o

エンジャパン
求む、社長!
follow us in feedly

コッチもヨロシク!





最近のネタ!

  1. 2019-9-17

    2019年8月度社員総会&懇親会@Nagoya

    気づけば夏の暑さも去ろうとしています。そんな9月うまれのおみです。 さて!少しお時間空いてしまいま…
  2. 2019-9-16

    [JavaScript] オブジェクト & 配列のイマドキなコピー方法 (スプレッド構文)

    オブジェクトや配列のコピーってどうやって書きますか? 皆さん JavaScript 書いてますか?…
  3. 2019-9-9

    Web で物理アニメーション・その5(最終回) 「ライブラリを使おう」

    前回の回答 前回の宿題は、バウンド時の跳ね返り方を制御するんでしたね。 では回答。 [code…
  4. 2019-9-6

    第3回 倶楽部ぽじてぃぶ ~釣り~

    2019年7月13日に、第3回となる倶楽部ぽじてぃぶの活動が開催されました! 今回は、その様子をお…
  5. 2019-9-2

    2019年8月度社員総会&懇親会@Osaka

    2019年8月6日(火)、大阪社員総会&懇親会が開催されました! その様子をお届けします! 社員総…
ページ上部へ戻る

当サイトに掲載されているコンテンツ(文書、画像等)は、許可なく複製・転用等する事を禁じます。

「フェアネス方式®」(登録6150741)は、日本国内における株式会社エージェントグローの登録商標です。

当サイトでは最低限必要と考えられる場合において、会社名/サービス名/商品名などを記載している場合があります。
これらはあくまでも説明の必要性に応じて用いているものであり、各社の権利等を侵害を目的とするものではございません。
不適切と考えられる場合には、当社お問い合わせフォームよりご連絡ください。

当サイトでは®や™などの表記を省略させていただいております。