現代的JavaScriptおれおれアドベントカレンダー2017 – 14日目

概要

オブジェクトとかでまとまってもらえる情報を、最初からバラバラにしちゃうやつです。

const data = {
  age: 99,
  id: id,
  name: 'Alice',
};

const { name, age } = data;
console.log(name);  // => "Alice"
console.log(age);  // => 99

配列もばらせます。別稿参照。

使い方

左辺ににょろ括弧 {} で括って、欲しいプロパティの名前を書きます。

const data = { id: 123, name: 'Alice' };

const { id, age } = data;
console.log(id);  // => 123
console.log(age);  // => undefined

右辺のオブジェクトから合致する名前のプロパティの値を代入します。 (id)

右辺にないもの (age) を指定すると undefined になり、また右辺にあるもの (name) を必ずしも左辺に用意する必要はありません。

かんたん、かんたん。

初期値

= で、値が undefined だった場合の初期値を設定できます。

const data = { id: 123, name: undefined };

const { name = 'Anonymous', age = 0 } = data;
console.log(name, age);  // => "Anonymous", 0

null は普通に代入されます。

入れ子

入れ子になった情報を取り出すこともできます。その場合、途中のプロパティは値が取得されません。

const data = {
  detail: {
    phone: {
      number: '0120-000-000',
      type: 'free',
    },
  },
};

const { detail: { phone: { number, type } } } = data;
console.log(number);  // => "0120-000-000"
console.log(type);  // => "free"
console.log(detail);  // Exception: ReferenceError: detail is not defined

異なる名前で

APIで情報を取ってきたは良いけどなんかその命名違うんだよなーみたいな場合にも使えます。

{ original: renamed } のようにして originalrenamed へ代入できます。

const data = { updated_at: '2017-12-14 00:00' };

const { updated_at: updatedAt } = data;
console.log(updatedAt);  // => "2017-12-14 00:00"

全部乗せ

初期値、入れ子、異名を全部組み合わせてもよろしい。

const data = { detail: { updated_at: '2017-12-14 00:00' } };

const {
  detail: {
    user_name: name = 'Anonymous',
    updated_at: updatedAt = 'NA',
  }
} = data;
console.log(name);  // => "Anonymous" (default value)
console.log(updatedAt);  // => "2017-12-14 00:00"

改行してもなお読みづらい感じはするね。うん、わかるよその気持ち。

関数の仮引数で

最初はちょっとぎょっとするかもしれないけど、仮引数の括弧の中でも使えます。

function sayHello({ message, delay = 1000 }) {
  setTimeout(() => console.log(message), delay);
}

sayHello({ message: 'Hello World!' });

必要なオプションが一目瞭然で良いかも。数が少ない間はね。

オプションオブジェクト option でざっくり受け取って、なんか中で処理を分けるとかすると良いかも?

function doGreatStuff(options) {
  doSomething(options);
  doAnything(options);
  doWhatever(options);
}

function doSomething({ foo }) {}
function doAnything({ bar }) {}
function doWhatever({ boo, hoge }) {}

その他

定義済み変数でSyntaxErrorになる

これはだめ。

const data = { foo: 'fufu' };

let foo;
{ foo } = data;  // Exception: SyntaxError: expected expression, got '='

行頭の { がブロックとみなされてしまうため。

括弧 () で括って式として判断させます。

const data = { foo: 'fufu' };

let foo;
({ foo } = data);
console.log(foo);  // => "fufu"

もちろん、普通にその場で変数宣言すれば問題ないです。

const data = { foo: 'fufu' };

const { foo } = data;
console.log(foo);  // => "fufu"

import

見た目は似てるけど違います。

import React, { Component } from 'react';
import { AppRegistry, Text, StyleSheet } from 'react-native';

雰囲気も似てるけど、動きも仕様も別物です。

destructuring assign

“destructure” は「破壊する」だそうです。あんまり一般的な語句ではないっぽい?

「分解代入」の方が意味的には適切なのかな。おれも分割代入って呼ぶけど。

デストラクタ destructor

じゃないです。コンストラクタの逆のやつ。

いや、まあこれはこれで欲しいことあるよね。いらない参照を明示的に切ったりとかイベント監視解除したりとかね。でも自動GCだからね。

参考

更新履歴

  • 2017-12-15 importは違うぞと言われてアアアーッッ!となって削除しました。たしかにいろいろ違います、すみません。