現役プログラマーによるJavaScript奮闘記5!~変数のスコープ編~

前回はJavaScriptの変数宣言と計算方法について記載しました。

今回はもう少し踏み込んだ内容について記載します。

■変数宣言のvarの省略

以前変数宣言には
var + 任意の文字列
と記載しました。

これは若干のうそがあります。
JavaScriptの場合、varを省略しても変数として代入することが可能です。

前回11を出力するのに

var val;
val = 10;
val = val + 1;
document.write(val);

と記載しましたが、varを省略して


val = 10;
val = val + 1;
document.write(val);

としても11が出力されます。

ただし、varを省略した変数は暗黙のグローバル変数として扱われます。
これが本当に厄介です。

いきなりグローバル変数といわれてもプログラム経験が無い人にはなんのこっちゃだと思うので、少し記載します。
(概念として、関数とかJavaでいうクラスとかメソッドの概念を理解しないと正確にはわからないです。)
なんとか例え話で説明しようとしていますが、わからなくても

変数にはグローバル変数とローカル変数があります。
ローカル変数は限られた範囲内でしか利用できず、範囲外からは利用できません。
グローバル変数はどこからでも利用できます。参照も上書きもできます。

学校のクラスを例にしてみます。
1年1組の出席番号20番が田中君でした。
1年2組の出席番号20番は高橋君です。

この【出席番号20番】という変数にそれぞれ【田中君】と【高橋君】を代入します。

イメージとしてはこんな感じ。ローカル変数版です。
——————————————————-
1年1組 {
var 【出席番号20番】 = 【田中君】;
}

1年2組 {
var 【出席番号20番】 = 【高橋君】;
}
——————————————————-
このようにローカル変数(varがついている)として書いた場合、
それぞれの変数に【田中君】と【高橋君】の情報が保持されます。

なので、1年1組の【出席番号20番】を出力した場合、どのタイミングでも【田中君】が出力されます。
1年2組から1年1組の【出席番号20番】を変更することはできません。

でもこのvarを省略して【出席番号20番】をグローバル変数とした場合以下のようになります。
——————————————————-
1年1組 {
【出席番号20番】 = 【田中君】;
}

1年2組 {
【出席番号20番】 = 【高橋君】;
}
——————————————————-
この【出席番号20番】は1年1組と1年2組で区別でされません。
そのため、順番に上から実行した場合、【田中君】の情報は【高橋君】で上書きされます。

なので、1年1組の【出席番号20番】を出力しようとしたときに
1年2組が実行されていた場合は【田中君】ではなく、【高橋君】が出力されます。

なんとなく伝わりますかね?

グローバル変数はどこから何されるかわからないです。
めっちゃ怖いです。

しかも暗黙のグローバル変数と書きました。
暗黙でされるのです。

たまたま全然意図せずたまたま同じ変数名になった場合、
知らないところで書き換えられまくります。

【出席番号20番の英語の点数】とかの変数名が被った場合、
【出席番号20番の英語の点数】 = 20点
とか書かれてしまうと全然違うクラスだったり、はたまた違う学年の【出席番号20番の英語の点数】で上書きされてしまうことがあるというわけです。

ちょっと管理しきれないですよね。

変数名にvarをつけれていれば暗黙のグローバル変数になることはありません。
そのため、変数名にはvarをつけましょうということでした。

また、varをつけてもグローバル変数にすることは可能です。
例えば【学校名】とかはそれぞれのクラスで共通なので、それぞれのクラスで定義する必要はないです。
こういった場合はグローバル変数にしてしまったほうが楽そうです。

その場合は枠の外にvarをつけて変数宣言します。

——————————————————-
var 【学校名】 = 【さわやか高校】

1年1組 {
var 【出席番号20番】 = 【田中君】;
}

1年2組 {
var 【出席番号20番】 = 【高橋君】;
}
——————————————————-

このようにすると【学校名】はグローバル変数になり1年1組からも1年2組からも参照可能です。
また、他の開発者が見たときに「あぁ、これは意図的にグローバル変数にしたんだな」とわかるので、
余計な心配をせずに利用することが可能になります。

そのため、変数名には必ずvarをつけるようにしましょう。

■定数について

他の人に値を変えてほしくない場合、定数という機構を利用します。

例えば上の例だと【学校名】は変更できる必要は無いですし、定数にしてしまったほうがよさそうです。

変数はvarで宣言しましたが、定数はconstで宣言します。

const SCHOOL_NAME = “さわやか高校”;

といった形になります。
定数は慣例として、全て大文字で記載します。

小文字でもエラーにはならないですが、プログラマーのお作法なので守っておいたほうが他の人に
「これは定数だよ!」ということが伝わって良いです。

定数の場合は大文字で書くようにしましょう。これは他の言語でも基本同様です。

定数宣言にはちょっとしたルールがあって、こういった、宣言と代入を2行に分けることはできません。


const SCHOOL_NAME;
SCHOOL_NAME = "さわやか高校";
document.write(SCHOOL_NAME);

Uncaught SyntaxError: Missing initializer in const declaration
というエラーになります(Chormeで実行したとき。他のブラウザだとちょっとメッセージが違うかも)。

また定数に対して、再代入はできません。
const SCHOOL_NAME = “さわやか高校”;
SCHOOL_NAME = “すこやか高校”;
document.write(SCHOOL_NAME);

このように一度初期化した定数に対して再代入すると
Uncaught TypeError: Assignment to constant variable
というエラーになります。

昔はこれエラーにならなかったみたいなので、「昔は動いていたけど突然うごかなくなった!」
見たいな事はありそうですね。

こんな感じで変数の注意点と定数について記載しました。

この変数のグローバル変数、ローカル変数については変数のスコープといったりしますが、
結構簡単にプログラムを破壊できてしまうので本当に要注意です。

しかも別にエラーになって異常終了するというわけではないので、
「気づかないうちにバグってる」という最悪のバグになりがちです。

今のうちから変数にはvarをつけるということを徹底しましょう

次回は今回からぽつぽつ出始めた関数について記載します。

ではー

コメント

タイトルとURLをコピーしました