var と let、const の使い方

作成日 : 2007-10-27
最終更新日 :

var の使い方

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
    }

let の使い方

上の 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 の使い方

一度変数に代入した値を変えない、という用途であれば、const キーワードを使うのが有効である。

function test_const() {
	const gamma = 0.5772156649;
	alert("オイラー定数は" +  gamma + "です");  
}

まりんきょ学問所JavaScript 手習い > var と let、const の使い方


MARUYAMA Satosi