Google Apps Script

変数宣言に「var」は使わない方が良い?「let」「const」との違いは?

Gmailが送れるなら誰でも無料で使える「GAS(Google Apps Script)」。
久しぶりに編集しようとしていたら、「V8 Runtime(ランタイム)」にアップデートされていました。
Google Apps Scriptのリリースノートによると、2020年2月5日からとのことです。

いったい何が変わったの?と、検索していたら、今まで使っていた変数宣言「var」を使わない方がいいという記述が多数見受けられました。
今まで「var」しか使ってこなかったので、そう言われると直した方がいいかなぁ?って思ってしまいます。

じゃあ、どんな風に直せばよいのか?
「Google Apps Script」で新しく使えるようになった変数宣言について、まとめてみました。

 

変数宣言の方法は?

今までの「var」の他に、新しく「let」と「const」が使えるようになりました。
この2つは「JavaScript」では数年前から使われており、「Google Apps Script」がそれに対応したのが今回のアップデートのようです。

 

違いは?

表にまとめてみました。

宣言方法 再宣言 再代入 スコープ バージョン
var 関数スコープ 以前から使える
let × ブロックスコープ 「V8 ランタイム」から
const × × ブロックスコープ 「V8 ランタイム」から

 

再宣言とは?

同じキーワードで変数を宣言することです。
「var」は再宣言ができて、「let」と「const」はできません。

function var_test(){
    var Number = 0;
    console.log(Number); // ⇒ 0が出力
 
    var Number = 1;
    console.log(Number); // ⇒ 1が出力
}
 
function let_test(){
    let Number = 0;
    console.log(Number); // ⇒ 0が出力
 
    let Number = 1;      // ⇒ ここでエラー「SyntaxError: Identifier 'Number' has already been declared」
    console.log(Number); 
}
 
function const_test(){
    const Number = 0;
    console.log(Number); // ⇒ 0が出力
 
    const Number = 1;    // ⇒ ここでエラー「SyntaxError: Identifier 'Number' has already been declared」
    console.log(Number);
}

 

再宣言によるデメリットは?

変数の巻き上げ(ホイスティング・Hoisting)が起こったとき、予期せぬエラーが出ます。
例えば、こんなコード↓

var Number = 0; //グローバル変数で宣言
 
function makiage_test (){
  console.log(Number); // ⇒ 「undefined」が出力
 
  var Number = 1;
  console.log(Number); // ⇒ 1が出力
}

最初の「console.log(Number);」で、「0」を出力したいのに、なぜか「undefined」になります。これが巻き上げです。JavaScript特有の概念だそうです。
ちなみに、「var」をつけない(再宣言しない)と、狙い通りになります。

var Number = 0; //グローバル変数で宣言
 
function makiage_test (){
  console.log(Number); // ⇒ 「0」が出力
 
  Number = 1;
  console.log(Number); // ⇒ 1が出力
}

 

再代入とは?

変数内の値を変えることです。
例えば、ループ処理で数字を1ずつ増やしたい場合は、再代入できる宣言法を使います。

function reassign_test (){
  for (let i = 1; i <= 100; i++){}
  for (const i = 1; i <= 100; i++){}    // ⇒ エラーが出る「TypeError: Assignment to constant variable.」
}

 

スコープとは?

直訳すると「範囲」のこと。変数の場合は、参照できる範囲のことを指します。
関数スコープは、「function」の中で使えます。
ブロックスコープは、「{}」の中で使えます。

関数スコープの例↓

function scope_test1() {
  var Number1 = 0
  console.log(Number1); // ⇒ 「0」が出力
}
 
function scope_test2() {
  console.log(Number1); // ⇒ エラーが出る「ReferenceError: Number1 is not defined」
}

「scope_test1」で定義した「Number1」は、「scope_test2」からは参照できません。

ブロックスコープの例↓

function blockScope_test() {
  for (let i = 1; i <= 3; i++){
    console.log(i); // ⇒ 「1」「2」「3」が出力
  }
  console.log(i); // ⇒ エラーが出る「ReferenceError: i is not defined」
}

for{}の外側なので、最後の「console.log(i);」では参照できません。

 

まとめ

「var」を使わない方がいい理由は巻き上げがあるからですね。
今後は「let」か「const」を使っていきます。
過去に作った物はどうしよう?
とりあえず「var」を「let」に置換して、コードを見ながら「const」に変えるのが良いかなぁと考えています。

-Google Apps Script
-, , , , , , , , , , , , , , ,