TypeScriptの変数について(var, let, const)

TypeScriptの変数

TypeScriptでは、変数の宣言はJavaScriptと同じルールに従います。

varletconstを使って変数宣言をすることができます。

var

TypeScriptの変数は、JavaScriptと同じようにvarキーワードで宣言することができます。

スコープの規則もJavaScriptと同じです。

let

ES6では、var宣言の問題を解決するために、JavaScriptにletとconstというキーワードを用いた2種類の新しい変数宣言が導入されました。

JavaScriptのスーパーセットであるTypeScriptも、これらの新しいタイプの変数宣言をサポートしています。

let employeeName = "John";

// もしくは

let employeeName:string = "John";

let宣言は、var宣言と同じ構文になります。しかし、varで宣言された変数とは異なり、letで宣言された変数はブロックスコープを持ちます。

つまり、let変数のスコープは、関数、if elseブロック、ループブロックなど、そのブロックを含むものに限定されます。

次のような例で考えてみましょう。

let num1:number = 1; 
    
function letDeclaration() { 
    let num2:number = 2; 

    if (num2 > num1) { 
        let num3: number = 3;
        num3++; 
    } 

    while(num1 < num2) { 
        let num4: number = 4;
        num1++;
    }

    console.log(num1); //OK
    console.log(num2); //OK 
    console.log(num3); //Compiler Error: Cannot find name 'num3'
    console.log(num4); //Compiler Error: Cannot find name 'num4'
}

letDeclaration();

上の例では、すべての変数がletで宣言されています。num3はifブロック内で宣言されているので、そのスコープはifブロック内に限定され、ifブロック外からアクセスすることはできません。

同様に、num4は whileブロックで宣言されているので、whileブロックの外からアクセスすることはできません。したがって、num3や num4をelse whereでアクセスすると、コンパイラのエラーになります。

同じ例でvar宣言をした場合は、エラーにならずにコンパイルされます。

var num1:number = 1; 
    
function varDeclaration() { 
    var num2:number = 2; 

    if (num2 > num1) { 
        var num3: number = 3;
        num3++; 
    } 

    while(num1 < num2) { 
        var num4: number = 4;
        num1++;
    }

    console.log(num1); //2
    console.log(num2); //2 
    console.log(num3); //4
    console.log(num4); //4
}

varDeclaration();

一見varの方がエラーを出さないので便利に思えますが、こちらの方が予期せぬバグを生む可能性が高くなります。

varよりletを使用するメリット

let変数は、宣言される前に読み書きできない

console.log(num1); // Compiler Error: error TS2448: Block-scoped variable 'num' used before its declaration
let num1:number = 10;

console.log(num2); // OK, Output: undefined 
var num2:number = 10;

上記の例では、TypeScriptコンパイラは、letで宣言する前に変数を使用するとエラーを出すが、varで宣言する前に変数を使用するとエラーを出しません。

let変数は再宣言できない

TypeScriptのコンパイラは、letを使って同じブロック内で同じ名前の変数(大文字と小文字を区別する)を複数回宣言すると、エラーを出します。

var num:number = 1; // OK
var Num:number = 2;// OK
var NUM:number = 3;// OK
var NuM:number = 4;// OK

let num:number = 5;// Compiler Error: Cannot redeclared block-scoped variable 'num'
let Num:number = 6;// Compiler Error: Cannot redeclared block-scoped variable 'Num'
let NUM:number = 7;// Compiler Error: Cannot redeclared block-scoped variable 'NUM'
let NuM:number = 8;// Compiler Error: Cannot redeclared block-scoped variable 'NuM'

上の例では、TypeScriptコンパイラーは変数名の大文字と小文字を区別して扱います。

numはNumと異なるので、エラーにはならない。しかし、同じ名前で大文字小文字を区別する変数についてはエラーとなります。

同じ名前と大文字小文字を持つ変数は、以下のように異なるブロックで宣言することができます。

let num:number = 1; 

function demo() {
    let num:number = 2;

    if(true) { 
        let num:number = 3;
        console.log(num); //Output: 3
    }

    console.log(num);//Output: 2
}
console.log(num); //Output: 1
demo();

同様に、以下のように、すでに関数の引数として渡された変数を宣言すると、コンパイラはエラーを出します。

function letDemo(a: number ) { 
    let a:number = 10 ; //Compiler Error: TS2300: Duplicate identifier 'a'
    let b:number = 20 ; 

    return a + b ;
}

このように、letで宣言された変数は、コンパイラがコンパイル時にエラーを出すため、実行時のエラーの可能性を最小限に抑えることができます。

これにより、コードの可読性と保守性が向上します。

const

変数は、varやlet宣言と同様にconstで宣言することができます。

constは変数を定数化し、その値を変更できないようにします。const 変数は、let 変数と同じスコープルールを持っています。

const num:number = 100;
num = 200; //Compiler Error: Cannot assign to 'num' because it is a constant or read-only property

const変数は、1つの文の中で宣言し、初期化する必要があります。

const num:number; //Compiler Error: const declaration must be initialized
num = 100; 

const変数は、オブジェクトのサブプロパティを変更することができますが、オブジェクトの構造を変えることはできません。

const playerCodes = { 
    player1 : 9, 
    player2 : 10, 
    player3 : 13, 
    player4 : 20
}; 
playerCodes.player2 = 11; // OK

playerCodes = {     //Compiler Error: Cannot assign to playerCodes because it is a constant or read-only
    player1 : 50,   // Modified value
    player2 : 10, 
    player3 : 13, 
    player4 : 20
}; 

以下のようにオブジェクト構造そのものを変更しようとしても、コンパイラがエラーを指摘します。

const playerCodes = { 
    player1: 9, 
    player2: 10, 
    player3: 13, 
    player4: 20
}; 

playerCodes = { //Compiler Error: Cannot assign to playerCodes because it is a constant or read-only
    player1: 9, 
    player2: 10, 
    player3: 13, 
    player4: 20, 
    player5: 22
}; 

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