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