Javascriptには省略型(=リテラル)がやたらと沢山あります。
ソースがスッキリするので基本的には推奨派ですが、やり過ぎると別言語に見えるぐらい可読性が悪くなるので「程々に使うのが良い」と私は考えます。
例えば6つ程「省略型」を使ってとある関数を実装してみる。
const moge = (...hoge) => hoge.reduce((x, y) => x + y); window.console.log(moge(1, 2, 3)); // 6

えーと、分かりません!
reduce関数から推測すれば何となくやりたい事は分かるから「読めなくは無い」けど「読みづらい」そんな印象。
本稿では配列・オブジェクト・関数の3種類の省略型で、やり過ぎない程度の書き方を提案したいと思う。
配列の省略型
まずは基本中の基本、配列について。
// new Arrayを使った記述 let arr1 = new Array("a", "b", 3); window.console.log(arr1); // 0: "a", 1: "b", 2: 3 // リテラルを使った記述 let arr2 = ["a", "b", 3]; window.console.log(arr2); // 0: "a", 1: "b", 2: 3
RubyやPHPでもお馴染みの書き方だし、使っている方も多いでしょう。
ただしJavascriptではnew Arrayとは微妙に挙動が違うので、ちょっとだけ気を付ける事。
new Arrayと[]の違いによる注意点
// new Arrayを使った記述 let arr1 = new Array(5); window.console.log(arr1); // [empty × 5] // リテラルを使った記述 let arr2 = [5]; window.console.log(arr2); // 0: 5
new Arrayは引数が1つの時だけ、挙動が変わります。
// 引数が正の整数の場合は、その数だけ空の要素を生成します。 let arr1 = new Array(5); window.console.log(arr1); // [empty × 5] // 引数がゼロの場合は、要素が無い配列が生成されます。 let arr2 = new Array(0); window.console.log(arr2); // [] // 引数が負の整数の場合はエラーになります。 let arr3 = new Array(-1); window.console.log(arr3); // Uncaught RangeError: Invalid array length // 引数が数値以外の場合は、その値の要素が1つだけ入った配列が生成されます。 let arr4 = new Array("a"); window.console.log(arr4); // 0: "a"
つまり、new Arrayを使うと
と言う事になるので、作りたければ
let arr = new Array(); arr[0] = 3; window.console.log(arr4); // 0: 3
こんな感じ。
素直にリテラルで記述した方が挙動も揃うし、微妙な気分にならずに済みます。
オブジェクトの省略型
Javascriptと言えばオブジェクト型!ってぐらいには使います、連想配列もオブジェクト型。
//new Objectを使った記述 let obj1 = new Object(); obj1.a = 1; obj1["hoge"] = 2; window.console.log(obj1); // a: 1, hoge: 2 // リテラルを使った記述 let obj2 = {a: 1, hoge: 2}; window.console.log(obj2); // a: 1, hoge: 2
非常に可読性が高くて超Cool。
// JSON形式風に記述 let obj = { "a": 1, "hoge": 2 }; window.console.log(obj); // a: 1, hoge: 2
JSON形式のように文字列のキーをダブルクォーテーションで囲んでもOKですが、JavascriptのオブジェクトとJSONは似て非なるモノです。
相互変換には必ずJSON.parseとJSON.stringifyを使いましょう。
型判定の時の注意点
Javascriptではややこしい事に、先述の配列もオブジェクトと判定されます。
let arr = new Array(); window.console.log(typeof arr); // object
違いは配列として生成されたオブジェクトはlengthプロパティを持っていたり、popやpush等の配列操作系のメソッドを持っている所。
渡されたオブジェクトが配列かどうかを判定したいよ!って場合は、
let arr = []; let obj = {}; window.console.log(arr.hasOwnProperty("length")); // true window.console.log(obj.hasOwnProperty("length")); // false
hasOwnPropertyでlengthプロパティが有るかどうかみたいな実装にするのが簡単かな。
関数の省略型
便宜上「関数の省略型」と書きましたが、実際はアロー関数(=function 式の代替構文)の事を指します。
このアロー関数は「○○なら省略可能」って条件がいくつも有って、
- ここは条件を満たしてるから省略だ!
- ここは条件を満たしていないからそのまま書く!
ってのを毎回やると、本当に見づらいソースになります。
本稿では、直感的にトレース出来る「程々具合」を考えてみる。
深く仕様を知りたい場合は「アロー関数 – JavaScript | MDN」こちらを熟読しましょう。
アロー関数の基本形
感覚的に理解するため、基本は「functionって書かなくても良い」と覚えるのが良いと思います。
// 基本の書き方 const moge = function(x, y) { window.console.log(x + y); }; moge(3, 6); // 9 // アロー関数を使った書き方 const hoge = (x, y) => { window.console.log(x + y); }; hoge(3, 6); // 9
new Arrayやnew Objectのリテラルと、似たような感じのイメージですね。
省略条件1(丸括弧の省略)
関数に渡す引数が1つの時は()を省略する事が出来ます。
// ()を省略しない const hoge1 = (x) => { window.console.log(x); }; hoge1(5); // 5 // ()を省略する const hoge2 = x => { window.console.log(x); }; hoge2(5); // 5 // 引数が2つ以上で()を省略するとシンタックスエラーになる const hoge3 = x, y => { window.console.log(x, y); }; hoge3(5, 7); // Uncaught SyntaxError: Missing initializer in const declaration // 引数が無い場合は省略できない const hoge4 = () => { window.console.log("hoge"); }; hoge4(); // hoge
()が無い事でエラーになるパターンが2種類あるので、()は省略せずに全部書いておけば見た目も統一されて良いと思います。
省略条件2(波括弧の省略)
関数内に式が1つだけしか入っていない時は{}を省略する事が出来ます。
// {}を省略しない let x1 = 5; const hoge1 = (x2) => { x1 += x2; }; hoge1(5); window.console.log(x1); // 10 // {}を省略する let y1 = 5; const hoge2 = (y2) => y1 += y2; hoge2(5); window.console.log(y1); // 10
式が二つ以上入っていたらネストしなきゃダメでしょってのは、直感的に理解出来ますね。
省略条件3(returnの省略)
関数内に式が1つだけしか入っていない時はreturnも省略する事が出来ます。
// returnを省略しない const hoge1 = (x) => { return x + 3; }; window.console.log(hoge1(5)); // 8 // returnを省略する const hoge2 = (y) => y + 3; window.console.log(hoge2(5)); // 8
老害と呼ばれるかも知れないけど「returnは明示的に書け」と言われて育ったので、略はしない方が良いと思います。
理由は第三者がソースを読む時、戻り値がある関数かどうかの確信を持てないのは余計な労力となり得るからです。
関数の可読性を上げる
冒頭に記した読みづらい関数、
const moge = (...hoge) => hoge.reduce((x, y) => x + y); window.console.log(moge(1, 2, 3)); // 6
コイツを以下の条件で書き直してみる。
- 丸括弧は省略しない。
- 波括弧は場合によっては省略する。
- returnは省略せずに明示的にする。
const moge = (hoge) => { return hoge.reduce((x, y) => { return x + y; }); }; window.console.log(moge([1, 2, 3])); // 6
随分と見やすくなりましたが、引数を配列に変更しちゃってるので例としてはあまりよく無かったですね(ごめん)
以上、Javascriptの省略型の書き方1(配列・オブジェクト・関数)でした。
コメント