JavaScriptでvarの変数宣言が再宣言できることはよく知られているが、ローカル変数とグローバル変数で命名被りしたときの動作を調べ直した。
一般的な変数宣言、再宣言の例
var str1 = "hello";
console.log(str1); // hello
var str1 = "world";
console.log(str1); // world
再宣言している箇所で再代入しても動作は同じ。
var変数にはブロックスコープがない
if (true) {
var str2 = "abc";
console.log(str2); // abc
}
console.log(str2); // abc ←if(false)の場合は、undefined
str2 = "xyz";
console.log(str2); // xyz
for (var i = 0; i < 3; i++) {
console.log(i); // 0 → 1 → 2
}
console.log(i); // 3
PHPもブロックスコープがないのでまあ読める。
グローバル変数とローカル変数で同名が存在する場合
本題。
グローバル変数とローカル変数で同名変数が存在する場合は別物として扱われる。
var str3 = "white";
var str3 = "red";
var str4 = "blue";
function func1() {
console.log(str3); // undefined ←グローバル変数と同名のローカル変数が宣言されているため
console.log(str4); // blue ←グローバル変数
var str3 = "yellow";
console.log(str3); // yellow
func2(); // red ←グローバル変数
}
function func2() {
console.log(str3);
}
func1();
ローカル変数とグローバル変数に同名の変数があると読むときに一瞬引っかかる。
まとめ
とにかく後勝ちと思っていれば読めはする。
ただし、ローカル変数とグローバル変数で命名被りが起こらないような命名ルールは必要。
新規開発でvarを使うことはもうないと思うけれど。