var の使い方を考える。
C 言語を使っていたときは、 変数の有効期間と可視範囲(スコープ)に絶えず気を使う必要があった。 自動変数は関数の内部でのみ有効なので、 関数の返値として使うときはいつも注意していた。 たとえば関数で配列を返すときには、自動変数で確保した領域を返すと、 関数を抜けたとたん解放されるのでバグを起こす。 動的に malloc で確保すると明示的に free をしなければ使い続けられる。 しかし今度は free のタイミングに苦労する。 もっとも、このような有効期間と可視範囲についての悩みは C 言語以外のほかの言語でもあると思う。
JavaScript ではこのあたりの事情がどうなっているかどうかを調べた。 var で宣言した変数が、関数の返値として使えるかどうか、また、関数の外から読めないかどうか、確かめた。 更に、var を付けない変数は、関数の外からも読めるかどうか調査した。 結論は次の通り。
function var1()
{
var a = [1, 2, 3, 4, 5]
return a
}
function var2()
{
var b = new Array(1, 2, 3, 4, 5, 6, 7)
return b
}
function var3()
{
c = new Array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
return c
}
function testvar()
{
var x
x = var1() // 1,2,3,4,5
alert(x)
x = var2() // 1,2,3,4,5,6,7
alert(x)
x = var3() // 1,2,3,4,5,6,7,8,9,10
alert(x)
// alert(a) // 表示できない
// alert(b) // 表示できない
alert(c) // 1,2,3,4,5,6,7,8,9,10
}
上の var の使い方は 2007 年に書いたものである。 当時はこれでよかったが、var にはバグを誘発しかねない危険な仕様があり、それは現在も続いている。 現在は var のかわりに let を使うべきである。
危険な仕様というのは、var がもつ、巻き上げ(ホイスティング、hoisting )という理解しにくい仕様のことをいう。 下記のサンプルコードを見てほしい。
var mia_nomo = "tuta";
function test_scope() {
alert(mia_nomo); // undefined ("tuta" ではない)
var mia_nomo = "loka";
alert(mia_nomo); // "loka"
}
上記のサンプルコードでは、アラートダイアログの最初に出力されるのは undefined である。 直感では "tuta" と思われるが、そうではない。 2 番目に出力されるのは "loka" である。これは直感と同じだ。 こうなる事情は、JavaScript で次のように決められているからだ。
JavaScriptでは、関数内で var 宣言されたローカル変数は、すべてその関数の先頭で宣言されたものとみなされる。
このような直感に反する挙動はバグを誘発する恐れがある。バグを予防する方法として、 まず、var は関数の先頭で宣言する、というプログラミングルールに従う方法がある。
var mia_nomo = "tuta";
function test_scope() {
var mia_nomo;
alert(mia_nomo); // "tuta"
mia_nomo = "loka";
alert(mia_nomo); // "loka"
}
別の方法は、var を使わずに let を使うことである。let は巻き上げを起こさない。 次のような挙動を示す。
第1のパターン
let mia_nomo = "tuta";
function test_scope() {
alert(mia_nomo); // "tuta"
// let mia_nomo = "loka"; // この行に代入はできない。
}
第2のパターン
let mia_nomo = "tuta";
function test_scope() {
// alert(mia_nomo); // 次の行を代入可能にするにはこの行は評価できない
let mia_nomo = "loka";
alert(mia_nomo); // "loca"
}
最近は、var の代わりに let を使うというのが主流である(2018-12-16)。
一度変数に代入した値を変えない、という用途であれば、const キーワードを使うのが有効である。
function test_const() {
const gamma = 0.5772156649;
alert("オイラー定数は" + gamma + "です");
}
まりんきょ学問所 > JavaScript 手習い > var と let、const の使い方