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 = 0console.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」に変えるのが良いかなぁと考えています。
