Google Apps Scriptで即時関数にクラスを定義する理由とその方法


immediate

photo credit: labuero Bobby Car Race via photopin (license)

みなさん、こんにちは!
タカハシ(@ntakahashi0505)です。

「初心者向けGoogle Apps Scriptでクラスを作る!」シリーズを連載でお伝えしています。

前回の記事はこちらです。

GASでdefinePropertiesメソッドを使ってクラスにプロパティを定義する方法
「初心者でもわかるGoogle Apps Scriptでクラスを作ろう!」をテーマとしたシリーズをお送りしています。今回はGASでdefinePropertiesメソッドを使ってプロパティを定義する方法です。

クラスにプロパティを定義するdefinePropertiesメソッドの使い方についてお伝えしました。

今回は、ちょっと方向を変えていきますね…

即時関数ですよ、即時関数。

Google Apps Scriptで即時関数にクラスを定義する理由とその方法についてお伝えします。

では、行ってみましょう!

スポンサーリンク

前回のおさらい

まず、以下のようなスプレッドシートの表があります。

スプレッドシートのテーブル

この表の各行を表すクラスを作成しているのですが、前回まで作成したのがこちらです。

function myFunction() {  
  
  var Person = function(record){
    var _id = record[0];
    this.name = record[1];
    this.gender = record[2];
    this.birthday = record[3];
    
    Object.defineProperties(this, {
      id: {
        get: function(){
          return _id;
        }
      }
    });
  };
  
  var values = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
  var p = new Person(values[1]);
  Logger.log(p.id);
  p.id = 'a00';
  Logger.log(p.id); 
  
}

ひとまずクラスとして形になってきましたね。

ただ、クラスPersonはmyFunctionの中で定義しているので、myFunctionの中でしか使用できないですよね。

他の関数からもクラスを利用したいときはどうすれば良いでしょうか?

クラスをグローバルに定義する

クラスPersonの定義、つまりコンストラクタをグローバルに定義しちゃいましょう。

  var Person = function(record){
    var _id = record[0];
    this.name = record[1];
    this.gender = record[2];
    this.birthday = record[3];
    
    Object.defineProperties(this, {
      id: {
        get: function(){
          return _id;
        }
      }
    });
  };
  
  Person.prototype.greet = function(){
    Browser.msgBox(this.name + "です、こんにちは!");
  };
  
  Person.prototype.log = function(){
    Logger.log('%s|%s|%s|%s|', this.id, this.name, this.gender, this.birthday);
  };

はい、OKです。

これでmyFunctionがスッキリです。

function myFunction() {  
    
  var values = SpreadsheetApp.getActiveSheet().getDataRange().getValues();
  var p = new Person(values[1]);
  
  p.log();
  
}

はい、以上お疲れ様でした!

…だと、この記事ちょっと密度が薄すぎますね。

即時関数でスコープを作る

今回の場合、グローバルに定義したとしても、まあそんなに大きな問題はないのですが、定義する関数や変数が全部グローバルスコープになってしまうのが、ちょっと心配ですよね。

うっかり、同じ関数や変数があったら、わけがわからない不具合が出ちゃいそうです。

それを防ぐために、 即時変数でスコープを作るという手があります。

即時関数とは

即時関数というのは、一回だけすぐに実行される関数です。

書式は以下の通り。

(function(仮引数1, 仮引数2,…) {
 //処理
})(引数1, 引数2,…)

名前がなくて、かっこで囲まれている感じですよね。

GASの話ですが、プロジェクト内のいずれかの関数が実行されたとき、グローバルに定義されているステートメントはその時点ですべて実行されます。

ですから、その辺のグローバルにポロっと置いてあるステートメントを、即時関数の中に入れ込んであげるんです。

すると、即時関数も関数ですから、その内部の変数や処理がローカルスコープに閉じ込めることができるというわけです。

すごいぞ!即時関数!

クラスを即時関数内に定義する

では、今回のクラスPersonをグローバル領域の即時関数内に定義してみましょう。

こちらです。

(function(global){

  var Person = function(record){
    var _id = record[0];
    this.name = record[1];
    this.gender = record[2];
    this.birthday = record[3];
    
    Object.defineProperties(this, {
      id: {
        get: function(){
          return _id;
        }
      }
    });
  };
  
  Person.prototype.greet = function(){
    Browser.msgBox(this.name + "です、こんにちは!");
  };
  
  Person.prototype.log = function(){
    Logger.log('%s|%s|%s|%s|', this.id, this.name, this.gender, this.birthday);
  };

  global.Person = Person;

})(this);

先ほどのmyFunctionを実行すると、ちゃんと以下のようにログが出力されるはずです。

インスタンスのデータをログを出力する

thisとglobalの意味

さて、この即時関数ですが、引数としてthisを渡して、それをglobalで受け取ってますね。

そしてさらに26行目ですが、globalのPersonにPersonを渡すという謎の処理が見受けられます。

これについて、ちゃんと理解しておく必要があります。

まず、thisですが、コンストラクタ内で使われているthisとは全く別の意味があります。

ここで使われているthisはグローバルのthisなのですが、その場合のthisはグローバルオブジェクトを表します。

それを、即時関数の仮引数のglobalに渡していますが、これはただの即時関数内で使用する仮引数です。

別にhogeでも良いわけです。

そして26行目。

global.Person = Person

これは、即時関数内で宣言したPersonをグローバルオブジェクトにも定義しているということですね。

ほら、コンストラクタPersonは即時関数内にありますからそのままではローカルスコープ。つまり、他の関数からは使用することができません。

それを、グローバルオブジェクトに渡すことで、プロジェクト内のすべての関数から呼び出すことができるようになるわけです。

まとめ

以上、Google Apps Scriptで即時関数にクラスを定義する理由とその方法についてお伝えしました。

GAS(というかJavaScript)はスコープがすごく重要ですよね。

あと、this。使う場所によって役割が変わりますので、要注意ですね。

次回は、インスタンスの集合を取り扱いしていきます。

Google Apps Scriptでスプレッドシートの表をインスタンス配列化する方法
「初心者でもわかるGoogle Apps Scriptのクラス」をテーマにシリーズ連載をお送りしております。今回は、GASでスプレッドシートの表をインスタンス配列化する方法をおお送りします。

どうぞお楽しみに!

連載目次:初心者向けGoogle Apps Scriptでクラスを作ろう

使いどころやそのメリットが分かりづらいGASの「クラス」。本シリーズでは、初心者でもわかるように「これでもか!」とじっくり着実にクラスとそのメリットについて解説をしていきます。
  1. 【初心者向け】Google Apps Scriptでクラスを理解するためのオブジェクトの基礎知識
  2. 初心者でもできるGoogle Apps Scriptで最も簡単なクラスを作る方法
  3. Google Apps Scriptでクラスに最も簡単なプロパティを追加する方法
  4. Google Apps Scriptでクラスに最も簡単なメソッドを追加する方法
  5. Google Apps Scriptでスプレッドシートのデータの1行分を表すクラスを作る方法
  6. GASでゲッターを使って簡単なプロパティを作成する方法
  7. GASでセッターを使ってプロパティの入力に制限をかける

タイトルとURLをコピーしました