2.1 変数と定数

(1/1)
喜ぶプログラムのキャラクター
ここから、JavaScriptでプログラムを書くためのルール(文法)を説明していく。
JavaScriptの文法は、Ecma Internationalが ECMAScript (エクマスクリプト) として標準化している。
ここでは、クラスが利用できるようになったバージョン ES2015(ES6) (2015年6月)に則って説明する。
まず、変数と定数の宣言や名前、有効範囲(スコープ)について事例を交えながら説明しよう。
(2024年1月23日)記事「定数」の中で掲示しているソースコードの誤りを訂正した。

目次

サンプル・プログラム

変数と名前

電卓のメモリ・キー
プログラムでデータ(数値、文字列など)を一時的に保管する場所として変数がある。電卓のメモリ・キー(M+)が複数あり、各々に自由に名前を付けられる仕組みと考えていただきたい。
変数の名前は識別子と呼ばれ、利用できる文字に制限がある。
JavaScriptの場合、半角英字、アンダースコア (_)、ドル記号 ($) から始まる文字で、続く文字には半角数字 (0–9) を使うことができる。英字は大文字と小文字を区別する。識別子の長さに制限はない。Unicode文字も使用できるとされているが、正常に動かないブラウザがあるので使用しない方がいい。半角数字から始めることができない点に注意。
プログラミング言語によって識別子の制限は異なるが、おおむねJavaScriptと同じと考えていい。
変数名は、誰でも分かるような読みやすいものにすべきだが、これについては「コラム:命名規則」をご覧いただきたい。

また、次の文字列はJavaScriptの予約語となっており、識別子(変数名や関数名)として使えない。背景色がライトブルーの予約語は、厳格モード等で使えないものをします。
await break case catch class
const continue debugger default delete
do else enum export extends
false finally for function if
import implements in instanceof interface
let new null package private
protected public return static super
switch this throw true try
typeof var void while with
yield while with yield  
予約語はプログラミング言語によって異なるが、少なくとも上表の文字列を使うのは避けた方がいい。

  19: <script>
  20: //ページのロード時に実行
  21: window.onload = function() {
  22:     let hoge = 1;
  23:     document.getElementById('let1').innerHTML = hoge;
  24:     let Hoge = 2;
  25:     document.getElementById('let2').innerHTML = Hoge;
  26:     let _hoge1 = 3;
  27:     document.getElementById('let3').innerHTML = _hoge1;
  28:     _hoge1 = 4;
  29:     document.getElementById('let4').innerHTML = _hoge1;
  30:     //let 3hoge = 4;
  31:     //document.getElementById('let2').innerHTML = 3hoge;
  32: }
  33: </script>

"var1.html" は、変数 hoge, Hoge, _hoge1 に数値を代入、表示させるプログラムだ。各々の変数名が異なるものとして区別されていることが分かる。
コメントアウトした変数 3hoge を実行しようとするとエラーになる。
たとえばGoogle Chromeでは、[F12]キーをクリックすると、下図のようにJavaScriptのエラーを表示するようになる。他のブラウザにも同様機能が備わっており、JavaScriptの簡易デバッガとして役立つだろう。

変数 _hoge1 を二度、使い回していることに注目してほしい。一度使った変数に別の値を代入することを再代入という。
再代入のときには let を使わない。let は変数を最初に使うときの宣言ととらえていただきたい。
ブラウザ:エラー表示

練習問題:変数と名前

グローバル変数とローカル変数

変数には有効範囲(スコープ)がある。
var 宣言した変数は、宣言した関数内またはプログラム全体(グローバルスコープ)で通用するグローバル変数(大域変数)になる。
let 宣言した変数は、宣言したブロック内(ブロックスコープ)で通用するローカル変数になる。
なお、JavaScriptでは window がグローバルスコープ上に常時存在するグローバル変数であるため、windowsを変数名として使うことはできない。

  19: <script>
  20: //ページのロード時に実行
  21: window.onload = function() {
  22:     //変数宣言
  23:     let a = 1;      //開始値
  24:     let b = 10;     //終了値
  25:     let n = 0;      //合計値
  26:     let s = '';     //計算式
  27:     let i = 100;    //グローバル変数
  28:     document.getElementById('let1').innerHTML = i;
  29: 
  30:     //aからbまでの整数の合計を求める
  31:     for (let i = ai <bi++) {   //ローカル変数
  32:         n +i;
  33:         s +i.toString();
  34:         //iが終了値でなければ計算式に+を追加する
  35:         if (i !b) {
  36:             s +'+';
  37:         }
  38:     }
  39:     document.getElementById('let2').innerHTML = s;
  40: 
  41:     document.getElementById('let3').innerHTML = i;
  42: }
  43: </script>

"var2.html" は、グローバル変数 iとローカル変数iのスコープの違いを見るものだ。プログラムの流れは、「1.5 画面表示 - 計算式と計算結果を画面に表示」で作ったものと同じである。実行結果は次のようになる。
100
1+2+3+4+5+6+7+8+9+10
100
もし変数iが全て同じスコープとして扱われるなら、プログラムの最初で100を代入しているが、forループ内で最終的に10を代入するので、最後の表示は10となるはずだ。
実際には、let宣言した変数iはforループのブロック内でしか通用しないので、var宣言した変数iには影響せず、上記のような結果となる。

このあと関数の説明をするが、異なる関数で同じ変数名を使うことがよくある。同じ名前の変数が影響し合わないように、そのスコープを明示的に宣言する習慣を身につけておこう。

定数

JavaScriptでは、const宣言を使って定数を宣言することができる。定数は、宣言した場所によってグローバルになったりローカルになったりする。
変数と定数の違い
変数 何度でも値を代入できる。
定数 一度しか値を代入できない
物理定数のような定数、WebAPIのコールURLなど、あらかじめ決まった値は定数で宣言しておくと、プログラムの中で間違って値を変更してしまうことができないから都合がいい。

  19: <script>
  20: //定数宣言
  21: const C0 = 299792458;       //真空中の光速(m/s)
  22: 
  23: /**
  24:  * 1光年を計算
  25:  * @const   C0
  26:  * @param   なし
  27:  * @return  float 1光年(km)
  28: */
  29: function lightYear() {
  30:     return C0 * 60 * 60 * 24 * 365 / 1000;
  31: }
  32: 
  33: //ページのロード時に実行
  34: window.onload = function() {
  35:     //変数宣言
  36:     let ly = lightYear();       //1光年(km)
  37: 
  38:     //結果を表示する
  39:     document.getElementById('C0').innerHTML = C0.toLocaleString();
  40:     document.getElementById('ly').innerHTML = ly.toLocaleString();
  41: }
  42: </script>

"const1.html" は、関数の外側で定数 CO(真空中の光速m/sを代入)を宣言しており、この定数がグローバルスコープを持つ。
関数 lightYear は光速を計算する。関数内でグローバル定数 CO を参照している。

実行結果は次の通り。
真空中の光速=299,792,458 m/s
1光年=9,454,254,955,488 km


多くのプログラミング言語では円周率のような数学定数はあらかじめ用意されているが(JavaScriptでは Math.PI)、物理定数は用意されていないことが多い。自力で定数宣言する必要がある。

練習問題:定数

練習問題:再代入

コラム:命名規則

マイコンBASICマガジン
マイコンBASICマガジン
パソコン黎明期のBASICでは、変数名を長くすると実行速度が低下するということがあった。また、C言語では、タイピング量を減らすために省略語を使うことが多かった。(例:stoi = string to integer)
現代のプログラミング言語は、変数名長の影響を受けることはないので、あとでプログラムを読み返したときや、他人がプログラムを読んだときに分かりやすい、簡潔な名前を付けるようにしよう。

変数や関数の名前の付け方を命名規則(ネーミングルール)と呼ぶ。命名規則はプログラミング言語の文法ではないが、会社やプロジェクトチームで決めていることが多い。
よくある命名規則の骨子は以下の通りだ。
  • 自然な英語で書く。例:year(年)
  • 単語と単語の間はアンダースコアでつなげるスネークケース(例:light_year 光年)と頭1文字大文字にするキャメルケース(例:LightYear 光年)がある。
  • グローバル変数は頭1文字を大文字にしたり(例:Speed_of_light 光速)、アンダースコアではじめる(例:_speed_of_light 光速)
このシリーズでは、スネークケースで、グローバル変数は頭1文字を大文字という命名規則とする。
(この項おわり)
header