サンプル・プログラム
平均を求める
例として、テストの平均点を求めるプログラム "average1.html" を作ってみよう。
左図がプログラムの実行例である。
115: //点数表
116: let scores = [75, 68, 81, 90, 57, 52, 96, 72, 68, 72];
この配列をユーザー定義関数 dispScoreTable に渡し、平均点を求めるとともに、点数一覧表を作成する。
36: /**
37: * 点数表を作成し,画面に表示する.
38: * @param Array scores 点数表
39: * @return なし
40: */
41: function dispScoreTable(scores) {
42: //エラーメッセージをクリア
43: document.getElementById('error').innerHTML = '';
44:
45: //配列のバリデーション
46: if (! Array.isArray(scores)) {
47: //エラーを表示
48: document.getElementById('error').innerHTML = 'エラー:正しい点数表を用意してください.';
49:
50: //点数表を作成
51: } else {
52: //点数合計と要素数をカウント
53: let sum = 0; //合計点数
54: for (let i = 0; i < scores.length; i++) {
55: let a = parseFloat(scores[i]);
56: //数字以外が含まれていたらNaNを代入して脱出
57: if (Number.isNaN(a)) {
58: n = sum = NaN;
59: return;
60: }
61: sum += a;
62: }
63:
64: //点数表の1行目
65: html =`
66: <tr>
67: <th>出席番号</th>
68: <th>点数</th>
69: </tr>
70: `;
71: //計算結果のバリデーション
72: if (Number.isNaN(sum)) {
73: //エラーを表示
74: document.getElementById('error').innerHTML = 'エラー:正しい点数表を用意してください.';
75:
76: //点数表を作成
77: } else {
78: for (let i = 0; i < scores.length; i++) {
79: html +=`
80: <tr>
81: <td>${i + 1}</td>
82: <td>${scores[i]}</td>
83: </tr>
84: `;
85: }
86: html +=`
87: <tr>
88: <td>合計点</td>
89: <td>${sum}</td>
90: </tr>
91: <tr>
92: <td>平均点</td>
93: <td>${sum / scores.length}</td>
94: </tr>
95: `;
96: //結果を表示
97: document.getElementById('scoreTable').innerHTML = html;
98: }
99: }
100: }
配列に格納されている要素の数は、length プロパティを使って取得できる。
要素の数だけ forループを回し、合計点と平均点を計算する。
あとは、点数表をTABLEタグとして組み立てる。
引数の参照渡し
19: <script>
20: // ユーザー定義関数 ========================================================
21: /**
22: * 引数に+1する(その1)
23: * @param Number a
24: * @return Number a + 1
25: */
26: function plus1(a) {
27: let b = a + 1;
28: return b;
29: }
30:
31: /**
32: * 引数に+1する(その2)
33: * @param Number a
34: * @return Number a + 1
35: */
36: function plus2(a) {
37: a = a + 1;
38: document.getElementById('var3').innerHTML = 'a = ' + a.toString();
39: return a;
40: }
41:
42: // メイン・プログラム ======================================================
43: window.onload = function() {
44: let a = 1;
45: document.getElementById('var1').innerHTML = 'A = ' + a.toString();
46: plus1(a);
47: document.getElementById('var2').innerHTML = 'A = ' + a.toString();
48: plus2(a);
49: document.getElementById('var4').innerHTML = 'A = ' + a.toString();
50: }
51: </script>
引数の値渡し
A = 1,2,3,4,5
A = 1,2,3,4,5
a = 1,2,3,5,5
A = 1,2,3,5,5
19: <script>
20: // ユーザー定義関数 ========================================================
21: /**
22: * 配列引数に+1する(その1)
23: * @param Array a 配列
24: * @param Number n 要素番号
25: * @return Number a + 1
26: */
27: function plus3(a, n) {
28: let b = a[n] + 1;
29: return b;
30: }
31:
32: /**
33: * 配列引数に+1する(その2)
34: * @param Array a 配列
35: * @param Number n 要素番号
36: * @return Number a + 1
37: */
38: function plus4(a, n) {
39: a[n] = a[n] + 1;
40: document.getElementById('var4').innerHTML = 'a = ' + a.toString();
41: return a[n];
42: }
43:
44: // メイン・プログラム ======================================================
45: window.onload = function() {
46: let a = [1, 2, 3, 4, 5];
47: let n = 3;
48: document.getElementById('var1').innerHTML = 'A = ' + a.toString();
49: plus3(a, n);
50: document.getElementById('var3').innerHTML = 'A = ' + a.toString();
51: plus4(a, n);
52: document.getElementById('var5').innerHTML = 'A = ' + a.toString();
53: }
54: </script>
配列をシャフルする
36: /**
37: * 指定した配列をシャフルする.
38: * @param Array arr シャフルしたい配列
39: * @return なし
40: */
41: function shuffle(arr) {
42: for (let i = arr.length; i > 1; i--) {
43: let k = Math.floor(Math.random() * i);
44: [arr[k], arr[i - 1]] = [arr[i - 1], arr[k]];
45: }
46: }
要素の数は lengthプロパティによって取得できる。
ランダムに要素を取り出すには、Math.random 関数を使う。戻り値が浮動小数なので、Math.floor 関数を使い、小数点以下を切り捨てる。
読みやすいプログラム:コメント
かつて、アセンブリやC言語のようなプログラミング言語では、関数や変数名が省略形であったり、独特なプログラミング記述法があったために、コメントは不可欠であった。
プログラムを読めば分かることをコメントに書くのは二度手間であるし、バージョンアップ時にいずれか一方の更新を忘れるとバグの温床になることから、コメントは必要最小限にとどめるべきというのが、今風の読みやすいプログラムとなる。
●コメントに記載する内容
- プログラム使用上の注意、制約条件など。
- プログラム使用にあたって準備すること、実施することなど。
- 参照しているライブラリ、フレームワーク、APIなどの情報。
- プログラムの著作権情報。
- コメントで補足しないと分からないような複雑な箇所。
- 変数やプロパティの1つ1つに対する解説。
- プログラムを読めば分かる内容。ただし、読み手のスキルに応じてコメントを付加すること。
- プログラムの更新履歴。ただし、バージョン管理システムを利用していない場合はコメントとして記述すること。
/**たとえば、次のようなコメントである。
* (1行目)機能概要【必須】
* (2行目)機能詳細,制約事項など【省略可能】
* @param{空白}変数の型{空白}変数名{空白}内容‥‥引数1の説明【省略可能】
* @param{空白}変数の型{空白}変数名{空白}内容‥‥引数2の説明【省略可能】
* (1行に1引数を記述する.)
* @return{空白}変数の型‥‥戻り値の説明【省略可能】
*/
/**
* 点数表を作成し,画面に表示する.
* @param Array scores 点数表
* @return なし
*/
関数/メソッド | 機能 | 詳細 |
---|---|---|
getLastModified | ファイル更新日を返す | |
dispScoreTable | 点数表を作成し,画面に表示する. |
読みやすいプログラム:引数の変更・上書きはしない
let a = 1;上のようなプログラムの場合、最初の領域に1が代入され、2行目には別領域が用意され、そこへ2が代入される。そして、変数 a の参照先を2番目の領域に更新する。
a = 2;
これが引数にしたときにも起きるので、じつは参照渡しに近いことをやっているのだが、結果的に値渡ししているように見える。
配列の場合は、配列が格納されている領域のポインタ(のようなもの)を渡す。引数で渡すときには、あらたな領域に代入されるのだが、そこには同じ値のポインタ(のようなもの)を代入するので、値渡しのように要素の値を変えることができる。
つまり、JavaScriptの場合、プリミティブ型でもオブジェクト型でも、仕様上は同じ方法で引数を渡している。これを共有渡しと呼ぶ方もいるが、正式な呼称はないようだ。
また、内部的にどのような渡し方をしているかはブラウザの実装によるので、実際に同じ方法で渡しているかどうかは分からない。
このあたりの事情は、@yuta0801氏の記事「JavaScriptに参照渡し/値渡しなど存在しない」に詳しい。
このようにJavaScriptの引数には癖があるため、引数の変更・上書きはしないことが読みやすいプログラムとなる。
引数は、見た目の上では、Number型やString型のようなプリミティブ型の場合は参照渡しで、配列などオブジェクト型は値渡しで渡される。(JavaScriptの引数渡しは、他の言語の参照渡しや値渡しとは異なる。)