読者です 読者をやめる 読者になる 読者になる

Processing.jsが出力するJavaScriptを調べてみる(1)

パズドラへ注ぎ込む額が徐々に増えています。ゴッドフェスに毎回つられてしまう…。私が悪いのではなくガンホーのせいですね。

ふと気になったので、今日はProcessing.jsでクラスを定義した際に、どのようなJavaScriptコードが出力されているか調べてみたいと思います。(かなりマニアックな内容です)

Processing.jsが出力するJavaScriptの確認方法

Processing.jsはProcessing言語(ほぼJava)をJavaScriptに変換して実行します。その際に次のようにcompileメソッドを使って手動で変換することで、出力されるJavaScriptコードの内容を確認することができます。

var processingCode = 'ここにProcessingコードを書く';
var jsCode = Processing.compile(processingCode).sourceCode;
console.log(jsCode);

クラス定義のJavaScriptコードの確認

ではクラスを定義した際にProcessing.jsがどんなJavaScriptコードを出力するか、次のProcessingコードで実際に試してみます。

class Person {
  String name;

  Person(String name) {
    this.name = name;
  }

  void greet() {
    println("Hello, I'm " + name + "!");
  }
}

void setup() {
  Person person = new Person("Stephanie");
  person.greet();
}

出力されたJavaScriptコード(をJavaScript Beautifierで見やすく整形したもの)は以下のとおりです。

// this code was autogenerated from PJS
(function ($p) {
  var Person = (function () {
    function Person() {
      var $this_1 = this;

      function $superCstr() {
        $p.extendClassChain($this_1)
      }
      $this_1.name = null;

      function greet$0() {
        $p.println("Hello, Im " + $this_1.name + "!");
      }
      $p.addMethod($this_1, 'greet', greet$0, false);

      function $constr_1(name) {
        $superCstr();

        $this_1.name = name;
      }

      function $constr() {
        if (arguments.length === 1) {
          $constr_1.apply($this_1, arguments);
        } else $superCstr();
      }
      $constr.apply(null, arguments);
    }
    return Person;
  })();
  $p.Person = Person;

  function setup() {
    var person = new Person("Stephanie");
    person.greet();
  }
  $p.setup = setup;
})

extendClassChainaddMethodなど、いくつか見慣れないメソッドが使われています。ソースを読んで内容を確認してみます。

extendClassChain

extendClassChainメソッドは作成対象のインスタンスに基底クラスのプロパティをコピーします。その際に、名前が同じで引数の数が異なるメソッドは別関数として扱い、引数の数に応じて呼び出し先を切り替える処理を追加します。

addMethod

addMethodメソッドはその名のとおり対象インスタンスにメソッドを追加します。同じ名前で引数の数が異なるメソッドの場合は、$overloadsという名前の関数テーブルを作成し、extendClassChainメソッドと同様に呼び出し先の切り替え処理を追加します。

長くなりましたので記事を2つに分け、次回は継承の実現方法とインスタンス作成時の処理内容について解説したいと思います。