JavaScript & GASの変数宣言:var, let, constの違いを初心者向けに解説

Google Apps Script
この記事は約11分で読めます。

はじめに

現代のJavaScriptは、ES6(ECMAScript 2015)以降、従来の「var」に加え、「let」と「const」という新しい変数宣言キーワードが導入され、コードの安全性や可読性、予測可能な動作を実現するための重要な手法となっています。Google Apps Script(GAS)においても、最新のV8ランタイムが採用されることで、これらのモダンな構文を活用できるようになりました。

キーワード比較表

キーワード スコープ 再宣言 再代入 備考
var 関数スコープまたはグローバルスコープ 可能 可能 意図しないグローバル変数生成のリスク
let ブロックスコープ 不可 可能 ブロック内でのみ有効
const ブロックスコープ 不可 不可 宣言時に初期化が必須

2. JavaScriptにおけるconst、let、varの基本

2.1 宣言方法と使用例

JavaScriptでは、以下の3種類のキーワードで変数を宣言できます。

  1. var
    • 概要: 関数スコープまたはグローバルスコープで変数を宣言し、再宣言と再代入が可能です。
    • 使用例:
      var x = 1;
      var x = 2; // 同じスコープ内で再宣言可能
      
    • 参考: freeCodeCamp1, W3Schools2
  2. let
    • 概要: ブロックスコープを持ち、同一スコープ内での再宣言はエラーとなりますが、値の再代入は可能です。
    • 使用例:
      let y = 1;
      y = 2; // OK
      // let y = 3; // 同じスコープ内で再宣言はエラー
      
    • 参考: MDN3
  3. const
    • 概要: ブロックスコープを持ち、宣言と同時に初期化が必須で、再代入および再宣言ができません(ただしオブジェクトの場合はプロパティ変更が可能です)。
    • 使用例:
      const z = 1;
      // z = 2; // エラー:再代入不可
      
    • 参考: MDN4, W3Schools5

2.2 スコープ、再代入、ホイスティングの違い

以下の点が各キーワード間の大きな違いです。

  1. スコープの違い
    • var: 関数スコープまたはグローバルスコープ。例として、関数内で宣言されたならばどこからでもアクセス可能です。MDN6
    • let および const: ブロックスコープで、宣言されたブロック内(if文、for文、{ } で囲われた部分)でのみ有効です。MDN3
  2. 再代入・再宣言
    • var: 再宣言と再代入が可能です。
    • let: 再代入は可能ですが、同一スコープ内での再宣言はエラーとなります。
    • const: 宣言時に初期化が必須で、再代入および再宣言はできません。ただし、オブジェクトの場合はその内部プロパティの変更は許容されます。MDN3
  3. ホイスティングの挙動
    • var: 宣言部分はホイスティングされ、未初期化状態として実行コードの先頭に持ち上げられ、暗黙的に「undefined」が割り当てられます。freeCodeCamp1
    • let および const: 同様にホイスティングはされますが、変数は実際の宣言までアクセスできず、宣言前のアクセスは「ReferenceError」を引き起こす(Temporal Dead Zoneの発生)。MDN3

3. Google Apps Script(GAS)における使用法と注意点

GASでは、最新のV8ランタイムが採用されており、JavaScript同様に「var」「let」「const」を使用できます。ただし、GAS特有の注意点があります。

3.1 GASでの変数宣言の基本

  1. var
    • 概要: 関数スコープで宣言されますが、関数外で宣言した場合はグローバルスコープとなり、意図しない上書きのリスクがあります。Google Developers7
    • 注意点: グローバル変数となると、スクリプト全体に影響を与えるため、慎重に使用する必要があります。
  2. let
    • 概要: ブロックスコープに限定され、if文やループ内で宣言された場合、そのブロック内でのみ有効です。sheets-pratique8
    • メリット: 変数の再宣言が禁止されるため、コードの意図が明確になり、バグを減らす効果が期待されます。
  3. const
    • 概要: 定数として宣言され、宣言時に初期化が必須。再代入ができないので、設定値や変更されない値に利用されます。spreadsheet.dev9
    • 注意点: オブジェクトの場合、内部プロパティの変更は可能ですが、変数そのものを別の値に再代入することはできません。

3.2 GASにおける変数宣言の特徴と注意

  • グローバル変数の生成
    GASでは、変数を宣言せずに値を代入すると暗黙のグローバル変数となり、予期せぬ上書きを引き起こす可能性があるため、必ず事前に宣言する必要があります。Google Developers7
  • スコープの管理
    varによるグローバル変数は意図しない上書きのリスクがあるため、基本的にはletやconstを利用してブロックスコープを意識した宣言を行うことが推奨されます。sheets-pratique8

3.3 エラー発生例とtry-catch実装サンプル

  1. エラー発生例
    letconstの宣言後に再宣言を試みると、以下のようなエラーが発生します。

    let a = 10;
    // let a = 20; // SyntaxError: Identifier 'a' has already been declared
    
  2. try-catch実装サンプル
    APIの制限によりエラーが発生した場合、以下のようにtry-catchでエラーハンドリングを行います。

    try {
        const response = UrlFetchApp.fetch('https://example.com/api'); // ここでAPI制限エラー
    } catch (error) {
        Logger.log('API制限によりエラー発生: ' + error.message);
    }
    

4. 実践的な使用例とベストプラクティス

ここでは、具体的なコード例を交えながら、どのようなシナリオでそれぞれのキーワードを使い分けるのが最適かを説明します。

4.1 JavaScriptでの使用例

  1. constの実践例
    • 用途: APIエンドポイント、設定値、数学定数など、変更される必要がない値を定義する際に利用
    • :
      const API_URL = 'https://api.example.com';
      const MAX_USERS = 100;
      const PI = 3.14;
      
    • 引用: ajahne.github.io10, overreacted.io11
  2. letの実践例
    • 用途: ユーザーインターフェースの状態管理、ループカウンタ、動的に変化する値
    • :
      let count = 0;
      for (let i = 0; i < 10; i++) {
        count += i;
        console.log(i);
      }
      
    • 引用: overreacted.io11, ajahne.github.io10
  3. varの実践例
    • 用途: 古いコードとの互換性が必要な場合、または明示的に関数全体で共有する必要がある変数の場合に限定して使用
    • :
      var globalSetting = true;
      function example() {
        var localValue = 10;
        console.log(localValue);
      }
      example();
      
    • 引用: W3Schools2

4.2 Google Apps Scriptでの使用例

  1. constの実践例(GAS)
    • 用途: 定数(例: シートID、APIキー)の宣言に使用し、コードの明確性を向上させる
    • :
      const SHEET_ID = '1234567890abcdef';
      // 使用例: SpreadsheetApp.openById(SHEET_ID);
      
    • 引用: Google Developers7, sheets-pratique8
  2. letの実践例(GAS)
    • 用途: 一時的な値やループ内のインデックス、ユーザー入力の一時的な格納
    • :
      function processRows() {
        let sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
        let numRows = sheet.getLastRow();
        for (let row = 1; row <= numRows; row++) {
          let cellValue = sheet.getRange(row, 1).getValue();
          // cellValueを利用した処理
        }
      }
      
    • 引用: sheets-pratique8
  3. varの実践例(GAS)
    • 用途: 旧コードの互換性を保つためや、明示的に関数スコープで扱う必要がある場合にのみ使用
    • :
      function legacyFunction() {
        var globalVar = 'This is a legacy variable';
        Logger.log(globalVar);
      }
      legacyFunction();
      
    • 引用: Google Developers7

4.3 変数命名規則の具体例

変数命名規則として、以下のようなスタイルを推奨します:

  • UPPER_SNAKE_CASE(定数): 定数にはすべて大文字の単語をアンダースコアで繋げた形式を使用。例: MAX_USERSAPI_URL
  • camelCase(変数): 変数名には小文字から始め、単語の先頭を大文字にした形式を使用。例: userCounttotalAmount

5. パフォーマンスとスコープ管理の観点からの考察

5.1 パフォーマンスの違い

  • constとletによるスコープ制御
    ブロックスコープを活用することで、JavaScriptエンジンは必要な変数アクセスの範囲を限定でき、意図しないグローバル変数へのアクセスを避けながら、メモリ使用量の最適化に寄与します。GeeksForGeeks12
  • varによるホイスティングの影響
    varはホイスティングによって宣言部分がスクリプトの先頭に上がるため、変数の初期値がundefinedとなり、意図しないタイミングで変数にアクセスされる可能性があります。W3Schools2

5.2 まとめの観点

最新のエンジンはletとconstを最適化しているため、正しく使えばパフォーマンス上の大きな違いはほとんどありません。しかし、コードの明確性・保守性、バグリスクの低減という観点では大きなメリットがあります。

6. 結論

この記事では、JavaScriptおよびGoogle Apps Scriptにおける「const」、「let」、「var」の各キーワードの使用方法、スコープ、再代入、ホイスティングの違いについて詳細に解説しました。まとめると、

  • var:従来の宣言方法。関数スコープまたはグローバルスコープで再宣言と再代入が可能ですが、ホイスティングや意図しないグローバル変数生成のリスクがあるため、新規コードでは避けるべきです。MDN6
  • let:ブロックスコープにより、必要な範囲で変数を管理でき、再代入は可能だが同一スコープ内での再宣言はできません。MDN3
  • const:宣言時に初期化が必須で、再代入不可のため、変更されない定数に最適です。MDN4

GASにおいても最新のV8ランタイムにより同様のルールが適用され、変数スコープの管理が特に重要となります。ベストプラクティスとしては、変更されない値はconst、必要に応じてlet、そして特殊な状況でのみvarを使用することが推奨されます。

7. 参考文献

  • freeCodeCamp1
  • MDN Web Docs – const4, let3, var6
  • W3Schools2, JS Const5
  • spreadsheet.dev9
  • sheets-pratique8
  • Google Developers7
  • ajahne.github.io10
  • overreacted.io11

まとめ

  • var は関数スコープまたはグローバルスコープで宣言され、再宣言と再代入が可能ですが、意図しないグローバル変数生成のリスクがあります。
  • let はブロックスコープで有効で、同一スコープ内での再宣言はエラーとなり、値の再代入は可能です。
  • const はブロックスコープで宣言時の初期化が必須で、再代入ができず、変更されない定数に適しています(オブジェクトの場合は内部プロパティの変更は可能)。
  • ホイスティングの挙動において、var は宣言が先頭に持ち上げられるのに対し、let と const は宣言前にアクセスすると ReferenceError が発生します。
  • GASでは最新のV8ランタイムにより、JavaScriptと同様に var、let、const を使用でき、グローバルスコープの変数管理に特に注意が必要です。
  • ベストプラクティスとして、変更されない値は const 、変更が必要な場合は let を使用し、互換性の理由でのみ var を使うことが推奨されています。

コメント