GASの変数のスコープを解説!グローバルスコープやブロックスコープの使い分けを紹介

Google Apps Script(GAS)の変数をうまく扱えるようになるにはスコープの概念を理解するのが大切です。

グローバルスコープやローカルスコープに加え、ブロックスコープなどがあるGAS変数のスコープについて解説します。

GAS変数のスコープとは?

Google Apps Script(GAS)の変数について学習していると、つまづきやすいポイントの1つがスコープという概念です。

スコープというのは、変数が参照できる範囲を表します。

変数は定義する場所によって、参照可能な領域が決定します。

あらゆる場所から参照できる変数のスコープもあれば、特定の領域内からしか参照できないスコープもあります。

この変数のスコープというのは、GASにかぎらず、あらゆるプログラミング言語で存在している概念です。

JavaやPython、C++などの様々なプログラミング言語

そのため、他のプログラミング言語を習得している人にとっては、同じ考え方なので、気になりません。

しかし、業務改善に取り組むため、GASを利用し始めた初学者にとってはかなり難易度の高いです。

グローバルスコープとローカルスコープの2つに大別

Google Apps Script(GAS)の変数スコープには、大きく以下の2つに分類されます。

  1. グローバルスコープ
  2. ローカルスコープ

グローバルスコープは、GASプロジェクト内のどこからでもアクセスできる変数スコープです。

GASの関数外で定義されたグローバル変数が、グローバルスコープに該当します。

グローバル変数は同じGASスクリプトファイル以外に、異なるスクリプトファイルで定義されても参照することができます。

それに対し、ローカルスコープはグローバルスコープのようにどこからでもアクセスできない変数です。

グローバルスコープとローカルスコープはMICEな関係なので、グローバルスコープでない場合はローカルスコープに該当します。

Google Apps Script(GAS)における変数スコープはグローバルスコープとローカルスコープの2つに大別

ローカルスコープは現在のGASでは、後述する関数スコープとブロックスコープに分かれます。

V8ランタイムのGASではブロックスコープも

ローカルスコープは、さらに関数スコープとブロックスコープに細分化することができます。

元々、Google Apps Script(GAS)のローカルスコープには、関数スコープしかありませんでした。

関数スコープは同一関数のみ参照可能

関数スコープというのは、GASスクリプトファイルで記述された関数内であれば参照可能なスコープです。

function localScope() {
  //varで定義した変数は関数内で実行可能な関数スコープ
  var funcVal = '関数スコープ';
  console.log(funcVal);
}

function test(){
  //別関数で定義された変数は呼び出せない
  console.log(fileName);
}
Google Apps Script(GAS)のvarによる変数宣言でのローカルスコープ(関数スコープ)のサンプルコードと実行結果

関数スコープなので、同じ関数(localScope関数)内では参照できますが、別関数からだと参照できずエラーします。

Google Apps Script(GAS)のvarによる変数宣言でのローカルスコープ(関数スコープ)の変数を別関数から呼び出してエラーした実行結果

このように同一関数内であれば参照可能、別関数からは参照不可なのが関数スコープな変数です。

V8ランタイムで利用可能なブロックスコープ変数

それから2020年にGASがアップデートされた際に、JavascriptのES2015(ES6)に対応したV8ランタイムが登場しました。

これによって関数スコープに加え、ブロックスコープがGASで使えるようになりました。

ブロックは、関数内の条件分岐や繰り返しループの中括弧{}内の範囲を意味します。

function blockScope() {
  if(true){
    //if文の中括弧内がブロックで、ブロックスコープな変数はこの中のみ有効

  }
  for(let i = 0; i < 10; i++){
    //for文の変数もブロックスコープなので、中括弧内のみ参照可能
    
  }
}

すなわち条件分岐内やforループ内で定義したブロックスコープの変数は、そのブロック内でのみ参照可能です。

関数スコープの変数であれば、forループ内で定義した変数もループ終了後にアクセスできますが、ブロックスコープではアクセスできません。

Google Apps Script(GAS)でlet宣言によるブロックスコープな変数の実行すると、if文の条件分岐外からは参照不可でエラー
function blockScope() {
  //関数の中括弧内で利用可能な変数を定義
  let val1 = '変数1';
  //if文の条件分岐内でのみ利用できる変数を定義
  if(val1 === '変数1'){
    console.log(val1);
    let val2 = '変数2';
    console.log(val2);
  }
  //条件分岐内で定義したブロックスコープ変数は参照できないのでエラー
  console.log(val2);
}

このように変数を参照できる範囲が「関数スコープ>ブロックスコープ」とより制限されます。

また、ブロックにはfunction関数の中括弧も大きいブロックと捉えることができるため、関数の中括弧内で定義した場合、関数スコープとブロックスコープは範囲が重なります。

ブロックスコープはvarではなくletを

従来の関数スコープの変数は、varコマンドを利用して定義していました。

それに対し、ブロックスコープの変数はletコマンドで定義します。

letコマンドはGoogle Apps Script(GAS)のV8ランタイム有効時のみ利用可能です。

Google Apps Script(GAS)のtruncはV8ランタイムでのみ利用可能

そのため、GASプロジェクト設定でV8ランタイムを無効にしていると、letによる変数定義はできないです。

古いGASスクリプトの場合は、V8ランタイムを無効にしていることも多いため、その場合は、varしか使えません。

なお、定数の場合もconstコマンドを使うと、letの変数と同じようにブロックスコープで定義可能です。

varやlet、constの変数・定数の宣言の使い分けは以下の記事で解説しています。

必要最小範囲に限定するブロックスコープがポイント

変数のスコープを考えると、どこからでもアクセスできるグローバルスコープを持つグローバル変数が便利です。

しかし、できるだけ参照できる範囲が小さいブロックスコープの変数を使うことが推奨されています。

なぜならば、変数が参照範囲はできるだけ必要最小限にすべきだからです。

セキュリティーにおけるアカウント管理でも、ユーザーが必要とする権限以上のアクセス権を与えません。

参照すべき情報にのみアクセスできるよう権限管理するのと同様に、変数も参照すべき範囲のみに制限すべきです。

そのため、変数の参照範囲を絞り込むことができるブロックスコープのletの利用が推奨されます。

ブロックスコープを鍵の管理で例えると

例えば、営業部や開発部などいくつかの部・課がある会社の建物の鍵の管理を考えます。

その会社にはどこの部署でも開けることができるマスターキー(グローバルスコープ)があったとしても、営業部の人や開発部の人にマスターキーを持たせません。

マスターキーを渡すと、営業部がアクセスすべきでない開発部の部屋まで開けることができるからです。

営業部の人には営業部の部屋が開けられる鍵(関数スコープ)、開発部の人には開発部の部屋が開けられる鍵(関数スコープ)を渡します。

さらに営業部の中でも1課、2課とそれぞれが部屋が分かれている場合は、各課にはそれぞれの部屋の鍵(ブロックスコープ)を渡すべきです。

建物の鍵を管理する際も、所属する人が必要な鍵のみを管理するのが一般的で、GAS変数でも同様に考えると、ブロックスコープになります。

GASでグローバルスコープを使うポイント

では、GASでグローバルスコープを使うポイントはどういったポイントになるでしょうか?

前述した通り、プログラミングにおいて、変数は利用する範囲にできるだけ限定すべきため、グローバルスコープの変数は使うべきではありません。

ただ、グローバルスコープ変数はスクリプトファイルの最上部に記述することが多く、どういった変数か分かりやすいメリットがあります。

そのため、スクリプトでアクセスするURL、GoogleドライブのドライブやスプレッドシートのIDなどをグローバルスコープに設定するのはケースも多いです。

Google Apps Script(GAS)でグローバルスコープのグローバル変数の仕様例
//初学者向けに読みやすくするため、グローバルスコープの変数を活用
//複数の関数で利用するURLやファイル名などを設定
let url = 'https://auto-worker.com/blog';
let fileName = 'ドライブファイル名.txt';

function globalTest(){
  console.log(url);
}

プログラミング初学者向けなどの場合は、分かりやすさを重視し、グローバルスコープも選択肢の1つです。

ただ、トークンやAPIキーなどはコードに直接記述すべきものではないため、スクリプトプロパティを利用しましょう。

まとめ・終わりに

今回、Google Apps Script(GAS)の変数が参照できる範囲を表すスコープについて紹介しました。

GASの変数スコープは、まずグローバルスコープとローカルスコープに大別され、ローカルスコープは関数スコープとブロックスコープに分けられます。

グローバルスコープ>関数スコープ>ブロックスコープの順番で変数を参照できる範囲がより限定されていきます。

GAS変数のスコープを考える上では、ブロックスコープのletによる定義が推奨されます。

最初のうちは難しいですが、スコープの考え方は例え話で挙げた鍵の管理でも同じ考え方です。

セキュリティーやアカウント管理の考え方に当てはめながら、変数スコープを考えてみると理解が深まるかもしれません。