◆変数とは
「データの入れ物」・「データを入れる箱」 と表現されることが一般的。
基本的にこのイメージで充分。
◆変数宣言
・ 変数の宣言とは
変数の名前の登録をJavascriptに登録し、かつ、値を格納するための領域をメモリ上に確保することを指す。
・ 変数宣言の書き方
変数を宣言するには、以下のように var 命令を使用する。
var 変数名
var 変数名 = 初期値
/**
* 例)
* var number = 10;
*
* var str = "Javascript";
*
*/
以下のようにカンマ区切りで複数宣言することも可能。
var x, y;
初期値を設定しなかった場合、Javascriptにはデフォルトで、
未定義(undefined) という時別な値が変数に割り当てられる。
【補足】 - 実は変数宣言は任意 -
Javascriptでは変数宣言は任意である。
具体例として、以下のようなコードは間違いではなく、問題なく機能する。
msg = "こんにちは";
console.log(msg);
// 出力: こんにちは
consoleで出力するタイミングでは、msgはvar命令で宣言をしていない。
つまり、これは変数宣言をしていないことになる。
にも関わらず処理が正常に動く理由は、
Javascriptが暗黙的に変数宣言を行ってくれるからである。
しかし、この変数宣言の省略は原則として避けるべきである。
理由や具体例は、 【番外】 -変数の参照について- で記載する。
・ 別の変数宣言 -let-
変数宣言を行うもう一つの命令として、let命令がある。
書き方は、var命令と同じ。
let 変数名;
let 変数名 = 初期値;
では、どのように使い分けたら良いのか。
・ letは変数の重複を許可しない
まず結論として、
変数宣言は基本的に 「let」 を使用する 事がおすすめ。
理由は変数名が重複した場合、letはエラーを発生してくれるから。
let msg = "Hello";
let msg = "See you";
/**
* Identifier 'msg' has already been declared.
* (msg は既に宣言されている。)
*/
一方varの場合、
var msg = "Hello";
var msg = "See you";
エラーは発生しない。
(この場合、msgの中身は See you で上書きされる。)
以上のようにvar命令の宣言は、気づかないところで宣言を上書きし、予期しないバグを生む可能性がある。
よって、変数宣言は基本的に let を使用するべき。
◆定数宣言
定数 は変数と概念は同じ。違うところは、
途中で中身を変更できない
という1点だけ。
・ 定数宣言の書き方
定数の宣言には、const命令を使用する。
const 定数名 = 値;
ここで注意する点は、
定数宣言では、宣言時に初期値の代入も必ず行う必要がある ということ。
変数宣言時のような、宣言だけを行うことはできない。
・ 定数宣言のちょっとしたルール
定数宣言は宣言時にconst命令を使用するだけで、他は変数宣言と変わりはない。
しかし定数であることを識別しやすくするよう、以下のようなルールで書くことが多い。
・全て大文字
・単語をアンダースコアで区切る
const DEFAULT_USER_NAME = "user name";
const CONSUMPTION_TAX = 1.10;
※このルールは強制ではいため、「上記のルールで必ず書かなければいけない」というわけではない。
◆識別子の命名規則
・ 4つの命名規則
識別子とは、互いを識別・区別するために付けられた名前のこと。
Javascriptでは自由に名前を決められるが、以下の4つの規則がある。
No | 規則 | 例 |
---|---|---|
1 | 1文字目は英字 or アンダースコア or ドル記号のどれか | name, _name, $name |
2 | 2文字目以降は、1文字目で使える文字、もしくは数字 | name1 |
3 | 変数名に含まれる英字の小文字・大文字は区別される | name と Name は別物 |
4 | Javascriptで意味を持つ予約語は使用できない | for, if, let など |
・ 予約語
Javascriptの予約語は下記サイトを確認すると良い。
・ 基本的は変数宣言の記法
ここでは、変数宣言で一般的に用いられる記法を紹介。
記法 | 概要 | 例 |
---|---|---|
camelCase記法 | 先頭の頭文字は小文字、それ以降の頭文字は大文字 | firstName |
Pascal記法 | 全ての単語の頭文字は大文字 | FirstName |
アンダースコア記法 | 単語同士をアンダースコアで連結 | first_name |
◆【番外】 - 変数の参照について -
更新履歴
・2022/10/3 : 「var」と「let」・「const」のスコープの違い を追加しました。
番外と記載しているが、この概念を理解しておく事は非常に重要。
・ 理解しておくべき用語
用語名 | 意味 |
---|---|
スコープ | 「変数がプログラムの中のどこから参照できるのか」を決める概念 |
グローバルスコープ | プログラム全体からアクセスができる |
グローバル変数 | プログラム全体からアクセスができる変数 |
ローカルスコープ | 定義された関数の中でのみ参照ができる |
ローカル変数 | 定義された関数の中でのみ参照ができる変数 |
関数 | 何かしらの入力値を与えることで、あらかじめ決められた処理を行い、その結果を返す仕組み |
具体例
// グローバル変数
let globalMessage = "GLOBAL";
/**
* 関数: callMessage
* 中でローカル変数を定義し、ローカル変数とグローバル変数の値を出力するという処理を実行する。
*/
function callMessage() {
// ローカル変数
let localMessage = "LOCAL";
// ↓ グローバル変数はどこからでもアクセス可能。
console.log(globalMessage);
console.log(localMessage);
}
// 出力: GLOBAL
console.log(globalMessage);
// 出力: GLOBAL LOCAL
console.log(callMessage);
// ↓ ローカル変数は宣言した関数の中でしかアクセスできないので、エラーになる。
console.log(localMessage);
・ 変数宣言を省略したらどうなるのか
結論としては、
宣言を省略して定義した変数は全て、グローバル変数として見做される
msg = "Hello";
function sleep() {
msg = "I'm sleepy";
console.log(msg);
}
// ③
console.log(msg); // 出力: I'm sleepy
// ④
console.log(sleep()); // 出力: I'm sleepy
とある事情により
③の出力では Hello を、
④では関数を使用し、 I'm sleepy を出力したいとする。
しかし関数内で宣言したmsgが、関数の外で宣言したmsgを上書きしてしまっている。
このような事象は予期しないバグの要因等になりかねないので、省略は基本的にはやらないようにすること。
・ 「var」と「let」,「const」のスコープの違い
結論
変数宣言 | スコープ | 説明 |
---|---|---|
var | 関数スコープ | 関数単位で参照が変わる |
let, const | ブロックスコープ | {}(ブロック)単位で参照が変わる |
・ 具体例(var で宣言した場合)
var a = "GLOBAL";
function num() {
var a = "LOCAL_1";
if(true) {
var a = "LOCAL_2";
console.log(`if文の中のaは${a}`);
}
console.log(`if文の外のaは${a}`);
}
console.log(`関数の外のaは${a}`);
num();
/**
* 出力結果
* 関数の外のaはGLOBAL
* if文の中のaはLOCAL_2
* if文の外のaはLOCAL_2
*/
上記のように、
関数num()内の 変数a の値が、
if文内の 変数a によって上書きされている。
つまりvarで宣言した変数は、同じ関数内であれば 参照も同じになる。
・ 具体例(let で宣言した場合)
let a = "GLOBAL";
function num() {
let a = "LOCAL_1";
if(true) {
let a = "LOCAL_2";
console.log(`if文の中のaは${a}`);
}
console.log(`if文の外のaは${a}`);
}
console.log(`関数の外のaは${a}`);
num();
/**
* 出力結果
* 関数の外のaはGLOBAL
* if文の中のaはLOCAL_2
* if文の外のaはLOCAL_1 ★
*/
上記のように、
関数num()内の 変数a の値と、
if文内の 変数a の値は異なっている。
つまりletで宣言した変数は、
同じ関数内でも、{}(ブロック)が違えば 参照も異なる。
目的に応じて使い分けるのも良いかもしれないが、
意図しないところで参照や値の上書きができてしまうvarではなく、
より範囲が限定的な let を使用するのが良い。
参考文献