オブジェクトで複数の値を返す
このレッスンで分かること
returnは値を 1 つしか返せないので、関連する値はオブジェクトに詰めて返します- 呼び出し側は名前で受け取れるので、順番を覚えずに済みます
合計と平均を、両方返したい
集計を書くと、すぐこの壁にぶつかります。合計も平均も欲しいのに、return sum, avg; とは書けません。JavaScript の return が返せる値は 1 つだけだからです。関数を 2 本に分ければ書けますが、同じループを 2 回まわすことになります。
前のレッスンでオブジェクトを覚えたので、ようやく答えが出せます。複数の値は 1 つの箱に詰めて返す、それだけです。
JavaScript
function measureBio(text) {
return { length: text.length, isEmpty: text.length === 0 };
}
const result = measureBio("フロントエンド");
console.log(result.length); // 7
console.log(result.isEmpty); // false呼び出し側は result.length のように名前で読めます。名前で受け取れることの本当の利点は、後から値を増やしても壊れないことです。キーを 1 つ足しても、既存の呼び出し側は今までどおりのキーを読み続けられます。
| 返し方 | 呼び出し側 | 向いている場面 |
|---|---|---|
| オブジェクト | r.length | 意味の違う値が並ぶとき |
| 配列 | const [min, max] = r | 順番が自明な 2 値のとき |
| 文字列に連結 | 自分で分解する | 表示専用のとき以外は避ける |
変数名とキー名がそろっているときは、片方を省略できます。第3章で一度出てきた省略記法です。
JavaScript
const width = 320;
const height = 180;
console.log({ width, height }); // { width: 320, height: 180 }0 件のときに NaN が出る
集計関数を書くときに必ず考えるのが、空の配列を渡された場合です。
JavaScript
const scores = [];
let sum = 0;
console.log(sum / scores.length); // NaN 0 割る 0 の結果要素が 0 個なら 0 / 0 の計算になり、結果は NaN になります。NaN は数値のようで数値ではない厄介な値で、一度混ざると、その後どれだけ計算しても NaN のままです。画面には「NaN 回」という意味不明な表示が出ます。
第3章の三項演算子で、0 件のときの答えを先に決めておけば防げます。「まだ作品が 1 件も無い状態」は、プロフィールサイトを公開した初日に必ず訪れる状態です。
小数を整数に丸めるには Math.round を使います。四捨五入なので、.5 は大きいほうへ寄ります。
JavaScript
console.log(Math.round(12.5)); // 13
console.log(Math.round(8.4)); // 8よくある間違い
returnの直後で改行する —returnだけの行があると、JavaScript は行末にセミコロンを補い、そこで文が終わったと解釈します。戻り値がundefinedになるので、return {は必ず同じ行に書きます- キー名を呼び出し側と食い違わせる — キー名は関数の外向きの約束です。つづりが違っても
undefinedが返るだけでエラーにならないので、気付くのが遅れます
要件
- 関数名は
summarizeViews、引数は数値の配列viewsの 1 つ - 戻り値は
totalとaverageの 2 つのキーを持つオブジェクト averageはMath.roundで四捨五入した整数にすること- 空配列のときは
{ total: 0, average: 0 }を返すこと
入出力例
summarizeViews([120,80,40]) → {"average":80,"total":240}
summarizeViews([100]) → {"average":100,"total":100}
summarizeViews([]) → {"average":0,"total":0}
summarizeViews([10,15]) → {"average":13,"total":25}
summarizeViews([0,0,0]) → {"average":0,"total":0}ヒント
編集 ゆめさく編集部