JavaScriptにおけるletとvarの違い

2015年 08月 04日

はてなブックマークはてブ
Google+1Google+
PocketPocket
JavaScriptにおけるletとvarの違い

    let宣言とは

    JavaScriptにおいて変数を宣言する場合にはvar変数を使用しますが、ES6(ECMAScript6)に基づいてコーディングされたソースコードにはvar宣言の代わりにlet宣言が用いられている場合があります。

    しかしながら、単純にvarがletに置き換わっているだけではないようなので、let宣言とvar宣言の違いについて調べてみました。

    結果を先に言うと、let宣言とは「局所変数の宣言」ということでした。

    let宣言は局所変数の宣言です

    たとえば、次のようにJavaScriptを記述してあるHTMLがあったとします。

    ファイル名はlet.htmlとでもしておきましょうか。

    <!DOCTYPE html>
    <html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>let</title>
    </head>
    <body>
        <p id="a1"></p>
        <p id="b1"></p>
        <p id="a2"></p>
        <p id="b2"></p>
    
        <script>
            "use strict";
    
            var a = 1;
            var b = 2;
    
            if (true) {
                let a = 10;
                var b = 20;
                
                document.getElementById('a1').innerText = 'let a: ' + a;
                document.getElementById('b1').innerText = 'var b: ' + b;
            }
    
            document.getElementById('a2').innerText = 'var a: ' + a;
            document.getElementById('b2').innerText = 'var b: ' + b;
        </script>
    </body>
    </html>
    

    これをブラウザで表示すると、このような表示になります。

    let a: 10

    var b: 20

    var a: 1

    var b: 20

    局所変数とは

    この出力結果がletとvarの違いです。

    if文の中で変数aをletで宣言し直していますよね。このとき、変数aは「局所変数」として宣言されています。

    対して変数bはif文の中でvarで宣言し直していますので、通常の変数のままです。

    局所変数を宣言すると、変数のスコープを「それが使用されたブロック、文または式に限定」することができます。

    つまり、ifやfunctionの内部でのみ反映される値を代入することができるわけです。

    局所変数の使い方の注意点

    上のソースコードでは、変数aとbの値をif文の内側と外側でそれぞれ出力させています。

    変数bではif文の中でも外でも同じ「20」という値が出力されていますね。
    一方で変数aではif文の中で出力している場合のみ「10」が出力され、if文の外では最初に代入した「1」が出力されます。

    let宣言による局所変数では、変数のスコープがlet宣言を含む文や式に限定されるため、たとえばlet.html内のJavaScript部分を次のように書き換えるとエラーになります。

    "use strict";
    
    //var a = 1;
    var b = 2;
    
    if (true) {
        let a = 10;
        var b = 20;
        
        document.getElementById('a1').innerText = 'let a: ' + a;
        document.getElementById('b1').innerText = 'var b: ' + b;
    }
    
    document.getElementById('a2').innerText = 'var a: ' + a;
    document.getElementById('b2').innerText = 'var b: ' + b;
    

    上のソースコードではif文の外でvar宣言し、変数aに10を代入している部分をコメントアウトしました。

    if文の中ではlet宣言により変数aが局所変数として宣言されているため、同じif文の中でしか参照できません。

    そのため、下から2行目に書かれている「document.getElementById(‘a2’).innerText = ‘var a: ‘ + a;」の部分を実行しようとすると、「Uncaught ReferenceError: a is not defined」とConsoleに表示され、エラーとなります。

    このように、局所変数のスコープ外から参照しようとしてエラーを起こさないように注意が必要です。

    let宣言はいつ使えばいいのか

    コンストラクタを仕様する際に let 文を用いることで、クロージャを使用せずにprivateなインターフェースを作成することができます。

    letを用いて宣言されたjはvarとは性質が異なり、各forループ時の処理で別々のインスタンスとして定義されます。その性質によって、実行時にjを解決する時はそれぞれのインスタンスを参照するため、きちんと期待される動作が得られます。

    この例を見てもわかるように、これまでfunctionをラップしてクロージャーを利用して解決していた手法よりも簡潔です。ECMAScript 6が導入された際に、主流の書き方となるかもしれません。

    とあるように、let宣言による局所変数はクロージャーの代わりに使うようです。

    カテゴリ:コーディング
    タグ:

    この記事をシェアする

    はてなブックマークはてブ
    Google+1Google+
    PocketPocket

    この記事へのコメント

    このサイトをシェア

    このサイトをシェアするボタンです。

    各記事ごとのシェアは各記事のタイトルの下のボタンから。

    SNSのアカウントのページへのリンクは画面最下部のフッター内にあります。