私の歴史と今

振り返ると恥ずかしくなるのが私の歴史。だけどそのときは真面目に書いていた訳でね。そんな今の私を書いていく。

JavaとJavaScriptの違い

これまでJavaScriptの言語仕様について勉強してきたので、Javaとの相違点を整理しておきたい。

コンストラクタ

これは似ている。
コンストラクタに対してnew演算子を使う点は同じ。Javaの場合は、クラス定義内のコンストラクタを呼び出す。それに対して、JavaScriptの場合は、単独の関数を呼び出す。
コンストラクタで初期化できるのも同じ。
違うのは、Javaにはコンストラクタを所有するクラス定義があり、既にインスタンス変数やインスタンスメソッドが存在しているので、インスタンス変数を初期化することができる。それに対して、JavaScriptにはクラスという概念がないので、コンストラクタを呼び出した段階では、プロパティ(Javaにおけるインスタンス変数/メソッド)が存在していない。そのため、初期化するといっても、プロパティの追加になる。
コンストラクタという概念の有無も異なるかもしれない。Javaには明確にコンストラクタというものがある。戻り値のないものがコンストラクタとなる。一方、JavaScriptにはコンストラクタ関数と一般関数を明確に区別する要素はない。すべての関数に対してnew演算子を使用できる。だから、コンストラクタ関数であるか否かは、その中身の作り方による。

// Javaの場合
class Program{
  private String name;
  Program(String name){ // コンストラクタはクラス定義内にある
    this.name = name; // 既に存在するメンバにアクセスできる
  }
  public static void main(String[] args){
    Program java = new Program("java");
    System.out.println(java.name); // java
  }
}
// JavaScriptの場合
var Program = function(name){ // コンストラクタ関数は単独で存在する
  this.name = name; // 既に存在しているプロパティはない。ここで追加している
}
var java = new Program('java'); // java
alert(java.name);

クラス

Javaにはクラスという定義があるが、JavaScriptには存在しない。ただ、便宜上、コンストラクタ関数の名前を指してクラスと呼ぶこともあるようだ(そう言った方が意思疎通できるからかもしれない。クラスを使った方が説明が楽)。JavaScriptにはクラスがないので、空のコンストラクタ関数を呼び出しただけの場合、生成されたオブジェクトにはプロパティが1つもない。クラスのインスタンス化と同じことをしたいのであれば、コンストラクタ関数内で必要なプロパティを追加することになる。

継承とプロタイプ

似てるようで根本的に違う。Javaの継承は、親クラスから子クラスへの継承。それに対してJavaScriptの継承は、プロトタイプからオブジェクトへの継承。Javaでは、子クラスのオブジェクトに対してメソッド呼び出しをした場合、そのメソッドが子クラスに定義されていればそのメソッドが実行され、もし定義されていなければ、親クラスのメソッドが呼び出される。その親クラスにもメソッド定義がなければ、更にその先祖クラスが探索される。それに対してJavaScriptでは、オブジェクトに対してメソッド呼び出しをした場合、オブジェクトにメソッドが設定されていればそのメソッドが実行され、もし設定されていなければ、そのオブジェクトのプロトタイプオブジェクトのメソッドが呼び出される。プロトタイプオブジェクトにもそのメソッドがなければ、そのプロトタイプオブジェクトのプロトタイプオブジェクトが探索される(メソッドチェーン)。
動的/静的という違いもある。でも眠いので明日。