JavaScriptを正しいスタイルで書けるようになりたい
一般的に安全で効率の良い書き方ってなんだろう
なるべく新しい仕様のJavaScriptでプログラミングしたい
JavaScriptはどちらかと言うと自由な書き方ができるプログラム言語と言えます。
そのため、人によって書き方が大きく異なり、また学習レベルによってもソースコードはずいぶんと違うものです。しかし、バラバラな書き方をしているとコードの共有が難しいばかりでなく、間違いも起きやすいのが現実でしょう。
一般的に正しいとされる作法を少し覚えるだけでも、ソースコードは大幅に読みやすくなります。
そこで、この記事では初心者でも今日からJavaScriptのコーディングスタイルを理解するための方法について分かりやすく解説していきますので、ぜひ最後まで読んで理解を深めて頂ければ幸いです。
- わかりやすいコードの記述には変数定義が重要
- コメントの書き方を統一するとチーム間で開発しやすい
- クラス構文を活用すればわかりやすいコードが作成できる
基本構文
この章では、JavaScriptの基本的な部分におけるコーディングスタイルのポイントをおさらいしておきましょう。主に、変数・条件式・コメントについて学んでいきます。
変数の作り方
JavaScriptは変数定義に【var】を使っていましたが、現在ではもう使うことはありません。
代わりに【let】【const】を利用するのですが、基本的に変数定義は【const】だけを使い、どうしても途中で変数の中身を変更する場合のみ【let】を使うと覚えておくと良いでしょう。
この2つの大きな特徴は以下の通りです
- 【let】再代入はOK、再定義はNG
- 【const】再代入はNG、再定義はNG
実際のプログラムにすると以下のようになります。
//letによる変数定義 let item1 = 100; let item1 = 10; //再定義はNG item1 = 1; //再代入はOK //constによる変数定義 const item2 = 100; const item2 = 10; //再定義はNG item2 = 1; //再代入はNG
このように、constは簡単に言うと定数を作るようなイメージに近いでしょう。そのため、letで定義されている変数はあとで変更処理があるんだな…と把握しやすくなるというわけです。
条件式のポイント
主にIF文でよく使われる条件式において、2つ以上の値を比較する時に注意するポイントについて見ていきましょう。
もっとも重要なのは、【等価演算子(==)】【厳密等価演算子(===)】の2つです。
例えば次のサンプル例を見てください。
const str = '1'; if(str == 1) { console.log('等しいです'); } else { console.log('等しくありません'); }
実行結果
等しいです
この例では、等価演算子(==)を条件式に利用していますね。比較しているのは数値の1と文字列の1ですが、結果は等しいことになっています。
つまり、等価演算子は【型】を自動的に変換してしまうので、値が同じなら【文字列】と【数値】で型が異なっているにも関わらずtrueを返してしまいます。
次に、厳密等価演算子(===)の場合を見てみましょう。
const str = '1'; if(str === 1) { console.log('等しいです'); } else { console.log('等しくありません'); }
実行結果
等しくありません
この場合は、型変換を行わないので値が同じでも【型】が異なっていればfalseを返してくれます。つまり、厳密等価演算子は名前の通り厳密に比較をしてくれるので、通常はこちらを使うようにするのが基本と言えます。
コメントの書き方
コメントは自由に書ける反面、人によって書き方がバラバラだと把握するのに余計な時間が掛かかってしまいがちです。
そこで、統一する意味も含めてよく使われるのがJSDocです。
例えば、次のサンプル例を見てください。
//ユーザー情報を管理するコンストラクタ function UserInfo(name, age) { this.name = name; //ユーザー名 //ユーザーの名前を返す this.getName = function() { return this.name; } }
この例は、単純なプロパティとメソッドを保持したコンストラクタと、よくありがちなコメントを一緒に併記しています。このようなコメントは人によって書く位置や内容が異なるので、コードを読むたびに把握しづらくなります。
そこで、同じサンプル例にJSDocによるコメントを記述してみましょう。
/** *ユーザーの情報を管理するコンストラクタ *@constructor *@param {String} name ユーザー名 *@return {String} ユーザーの名前を返す */ function UserInfo(name, age) { this.name = name; this.getName = function() { return this.name; } }
/** 〜 */ の範囲に書かれたコメントが、JSDocで記述されたコメントになります。内容は、コンストラクタであること、どんなプロパティやメソッドがあるのか記載されているので、最初にコメントを見るだけでコードの内容が把握しやすくなります。
また、各プロパティやメソッドにもさらに詳しいコメントを併記できます。
function UserInfo(name, age) { /** *ユーザーの名前 *@type {String} */ this.name = name; /* *ユーザーの名前を取得します *@return {String} ユーザー名 */ this.getName = function() { return this.name; } }
このJSDocはコメントの分かりやすさや統一感はもちろんですが、対応するエディタで利用すると自動的にコード補完に反映されるという特徴もあるので便利です。
繰り返し処理
この章では、繰り返し処理のベストプラクティスについて見ていきましょう。主に、配列要素の取得などでよく使う繰り返し処理について学んでいきます。
配列の繰り返し処理
配列の要素を取り出す時に、よく使う繰り返し処理としてはfor文やforEach文などがあります。
これらのメソッドは万能なので、ついついあらゆるケースで使いたくなるわけですが、用途に応じて他のメソッドを併用するのが効果的です。
例えば、条件によって配列要素を抽出したい場合についてはfilter()メソッドが最適です。
const list = [50,450,255,500,70]; const result = list.filter(data => { if(data>300) return true; }) console.log(result);
実行結果
[450, 500]
この例では、配列要素の中から300以上の数値だけを抽出しています。
filter()を使うと、ソースコードを見た人が何らかの条件で要素を抽出しているんだな…というのがコメントを書かなくても理解しやすいというメリットがあります。
他にも、配列を利用して別の配列作りたい場合にはmap()メソッドがあります。
const list = [5,45,255,500]; const result = list.map(data => { return data * 2; }) console.log(result);
実行結果
[100, 900, 510, 1000, 140]
この例では、配列要素の値をすべて2倍にした新しい配列を作成していますね。
このメソッドも他の人が見た時に、何か新しい配列を生成しているんだな…というのが把握しやすくなります。
このように、配列には便利なメソッドがいくつか提供されているので、まず最初に検討してみてどうしても意図に合わない場合のみfor / forEachなどを利用してみてください。
クラスについて
この章では、JavaScriptにおけるクラスを作成する処理について見ていきましょう。主に、ES6から導入されたclass構文やメソッド定義・継承について学んでいきます。
クラスの作り方
JavaScriptでクラスのようなものを作ろうと思った時に、これまでは関数を定義するのに使っていたfunctionを次のように利用してました。
function User(name, age) { this.name = name; this.age = age; } const taro = new User('太郎', 30);
この例ではUserコンストラクタを作成し、newを使ってtaroインスタンスを作成しています。
JavaScript以外の言語を利用されている人が見たら直感的に分かりづらい定義なのですが、ES6になってJavaScriptにもclass構文が提供されたので次のように記述することができるようになりました。
class User { constructor(name, age) { this.name = name; this.age = age; } } const taro = new User('太郎', 30);
ソースコードを見た時にクラスを定義していることがはっきり明確になり、コンストラクタも分かりやすくなりました。class構文が裏でやっていることは、これまでfunctionを利用していた時と内容的には同じなのですが直感的に扱いやすくなっています。
メソッド定義と継承について
class構文はメソッド定義や継承を行う際にも便利に扱えるのでご紹介しておきます。
これまでは、メソッドを定義する際にメモリの効率などを考えてプロトタイプを利用して次のように記述していました。
function User(name, age) { this.name = name; this.age = age; } User.prototype.getName = function() { console.log(this.name); }
User.prototypeに続けて定義したいメソッド名と処理内容を記述していますね。初心者の人だと理解が難しいうえあまり直感的に分かりやすいコードとは言えません。
しかしclass構文を利用すると、プロトタイプをあまり意識せずに分かりやすく記述できます。
class User { constructor(name, age) { this.name = name; this.age = age; } getName() { console.log(this.name); } }
このようにclass構文の中でメソッド定義を行い、1つにまとめられるので分かりやすいですね。
さらに、継承についてはもっと直感的に扱えるようになります。これまではプロトタイプを利用して次のように継承していました。
const Human = function() {} Human.prototype.speak = function() { console.log('こんにちは!'); } const Boy = function() {} //HumanをBoyに継承する Boy.prototype = new Human();
継承先にprototypeを利用してnewを実行することで継承を実現したいたわけですが、class構文を利用すると次のように簡潔に記述できます。
class Human { speak() { console.log('こんにちは!'); } } //HumanをBoyに継承する class Boy extends Human {}
クラスを定義する際にextendsを利用して継承を簡単に行なえます。また、ソースコードを見た時に継承のフローが明確で把握しやすいというメリットもあるわけです。
まとめ
今回は、JavaScriptのコーディングスタイルのベストプラクティスをいくつか学習しました。
最後に、もう一度ポイントをおさらいしておきましょう!
- let / const、比較演算子、コメントの書き方について注意する
- 配列の繰り返し処理は用途に応じたメソッドを利用する
- class構文を積極的に利用して理解しやすく記述する
上記内容を踏まえて、ぜひ自分でもプログラミングに取り入れて活用できるように頑張りましょう!