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

概要

= で初期値を設定できます。

いままでこう↓してたのを、

function findRestaurant(type) {
  if (type === undefined) {
    type = 'sushi';
  }

  // ...
}

こう↓書けます。

function findRestaurant(type = 'sushi') {
  // ...
}

初期値が適用される場面

元のコードで条件として if (type === undefined) を示しましたが、新しい書き方でも条件は同じです。

書かなかった場合だけでなく、明示的に undefined を指定した場合も適用されます

function say(message = 'Yo!') {
  console.log(message);
}

say();  // => "Yo!"
say(undefined);  // => "Yo!"
say(null);  // => null

単純に元の if (type === undefined) の置き換えって感じっすねー。

引数の設定

途中のものだけでも

Javaとかだと初期値って仮引数群の後ろからじゃないと与えられないと思うんですけど、JavaScriptだとそんなことなくて、なんと、途中にだけ付けることができます。

function makeSushi(neta, shari = 'sumeshi', wasabi) {
  console.log(neta, shari, wasabi);
  // ...
}

makeSushi();  // => undefined, "sumeshi", undefined
makeSushi('tuna');  // => "tuna", "sumeshi", undefined
makeSushi('tuna', 'katame', true);  // => "tuna", "katame", true

初期値のないもの wasabi は当然 undefined になります。

これも単純に元の if (type === undefined) の置き換えって感じっすねー。

引数から引数を利用する

左から順に評価されていくので、左側の引数を使った初期値を設定することができます。

function numbers(n = 1, m = n * n, l = n + m) {
  console.log(n, m, l);
}

numbers();  // 1, 1, 2
numbers(3);  // 3, 9, 12
numbers(3, 5);  // 3, 5, 8

うひゃあ。

改めて単純に元の if (type === undefined) の置き換えって感じっすねー。

分割代入と組み合わせる

大変便利な分割代入については別稿参照。

便利だけどなかなか読みづらいので、ご利用は計画的に。

function makeDog({ type = 'shiba' } = { type: 'mix' }) {
  console.log(type);
}

makeDog();  // "mix"
makeDog({});  // "shiba"
makeDog({ type: 'samoyed' });  // "samoyed"

右辺 { type: 'mix' } が引数自体の初期値で、左辺の type = 'shiba' は分割代入時の初期値です。

正直ここちょっとよくわかってないです。

右辺は実行時に評価

関数を実行するとき、 undefined が与えられた際、初期値(右辺)が評価されます。

この例↓だと毎回実行時の時刻になります。

function sayTime(now = new Date()) {
  console.log(`It is ${now.getHours()}:${now.getMinutes()}:${now.getSeconds()} now.`);
}

やっぱり単純に元の if (type === undefined) の置き換えって感じっすねー。

引数未指定時に例外

前項の仕様を使うと、必ず引数を書かせるようにもできます。

function throwNewError(name) {
  throw new Error(name);
}

function sayTime(now = throwNewError('Now is required')) {
  // ...
}

sayTime();  // Exception: Error: Now is required

どこで見かけた話だったかな。例外発生個所が変な場所になっちゃうのであまり実用的ではない気がする。

ちなみに = の右辺に throw は書けないです。

参考

初期値を適用する条件( undefined を与えられたとき)の定義は見つけられませんでした。