中級者向けの記事になります。
JavaScript の定数定義を行うときに、関連した複数の値をまとめたいときがあります。そういうときにどのように書くのがよいのか、ということについてまとめておきます。
下手なコード
このようなコードをみかけました。
1 2 3 4 5 6 7 8 |
const ACCOUNT_TYPE1 = [ { id: 1, name: 'President', description: '取締役' }, { id: 2, name: 'Executive', description: '役員' }, { id: 3, name: 'Manager', description: '管理職' }, { id: 4, name: 'Member', description: '社員' } ]; console.log(ACCOUNT_TYPE1[0]); // { id: 1, description: '取締役' } と表示される |
これはかなりまずいコードです。
定数値として、値を保持したいのはわかりますが
ACCOUNT_TYPE[0] が 取締役のデータをもっているかどうかをプログラマが事前に暗記でもしておかなければみつけられないコードになってしまいます。
取締役が0で、役員が1とかの値かどうかはプログラムを読む人は覚えたりしていませんし覚えたくもありません。
少しよいコード
1 2 3 4 5 6 7 8 |
const ACCOUNT_TYPE2 = { President: { id: 1, description: '取締役' }, Executive: { id: 2, description: '役員' }, Manager: { id: 3, description: '管理職' }, Member: { id: 4, description: '社員' }, } console.log(ACCOUNT_TYPE2.President); // { id: 1, description: '取締役' } と表示される |
このようにすると少しはましでしょう。
ACCOUNT_TYPE.President が取締役のデータをもっていることが誰がプログラムコードを読むときにでも読みやすくなります。
データを記録する場合に id よりかは名称、この場合は President という文字列を使いたい場面もあったりします。President という文字列でこのデータを見つけることができないので、まだちょっといまいちかもしれません。
よりよいコード
1 2 3 4 5 6 7 |
const ACCOUNT_TYPE3 = { PRESIDENT: { NAME: 'President', ID: 1, DESCRIPTION: '取締役' }, EXECUTIVE: { NAME: 'Executive', ID: 2, DESCRIPTION: '役員' }, MANAGER: { NAME: 'Manager', ID: 3, DESCRIPTION: '管理者' }, MEMBER: { NAME: 'Member', ID: 4, DESCRIPTION: '社員' } } console.log(ACCOUNT_TYPE3.PRESIDENT); |
データ構造としてはこんなふうなものがいいかもしれません。これなら、データにアクセスするのも容易ですし、NAMEプロパティで英語名でもデータ検索できるようにプログラムを組むことも容易です。
定数としては、ACCOUNT_TYPE3.PRESIDENT としてデータにアクセスすることができます。
このデータを作り出すように少し工夫をしてみます。
データを作るための関数
DESCRIPTION とかを何度も書くのは冗長かな、とも思いますので、makeObject という共通関数をつくってからそれにあわせてデータを生成してみます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
function makeObject(keyArray, valueArray) { if (keyArray.length !== valueArray.length) { throw new Error('makeObject key value length is invalid.'); } const result = {}; keyArray.forEach((key, index) => { result[key] = valueArray[index]; }); return result; } const ACCOUNT_TYPE4 = makeObject( [ 'PRESIDENT', 'EXECUTIVE', 'MANAGER', 'MEMBER' ], [ ['President', 1, '取締役'], ['Executive', 2, '役員'], ['Manager', 3, '管理者'], ['Member', 4, '社員'] ].map( (item) => makeObject( 'NAME,ID,DESCRIPTION'.split(','), item ) ) ); console.log(ACCOUNT_TYPE4); // 出力結果 // { PRESIDENT: { NAME: 'President', ID: 1, DESCRIPTION: '取締役' }, // EXECUTIVE: { NAME: 'Executive', ID: 2, DESCRIPTION: '役員' }, // MANAGER: { NAME: 'Manager', ID: 3, DESCRIPTION: '管理者' }, // MEMBER: { NAME: 'Member', ID: 4, DESCRIPTION: '社員' } } |
これで、ACCOUNT_TYPE3と全く同じACCOUNT_TYPE4 を生成することができます。
冗長のように思えるかもしれませんが、makeObject は使い回しのできる汎用関数としてプロジェクト内の共通関数部分で記載すればよく、ライブラリ側に隠蔽できると考えると ACCOUNT_TYPE4 の代入部分だけなので短くて済みます。
このようにしておくとデータの定義が便利に行えるでしょう。
応用効かせて、よいコードを書いていってみてください。