Class-Based vs. Prototype-Based Languages

클래스 기반언어와 프로토타입 기반언어

Java와 C++이라는 클래스 기반의 객체지향언어는 클래스와 인스턴스라는 2개의 다른 실체가 있다는 개념에 기초하고 있습니다.

  • 클래스는 어떤 객체의 집합을 특징짓는 모든 속성(Java에서는 메소드와 필드를, C++에서는 멤버를 프로퍼티로 간주)을 정의합니다. 클래스란 그것이 나타내는 객체집합의 특정멤버가 아닌, 추상적인것입니다. 예를들어, Employee클래스는 모든 종업원의 집합을 나타냅니다.
  • 한편, 인스턴스는 클래스를 실례로 한것입니다. 즉, 그 멤버중 하나인것입니다. 예를들어, Victoria는 Employee클래스의 인스턴스가 될 수 있습니다. 이 클래스는 특정 개인을 종업원으로서 표현하고 있는것입니다. 인스턴스는 그 부모클래스의 속성을 정확하게 유지하고 있습니다.

JavaScript のようなプロトタイプベース言語はこの区別がありません。単にオブジェクトがあるだけです。プロトタイプベース言語には原型的なオブジェクトという概念があります。このオブジェクトは新しいオブジェクトの初期プロパティを取得する元になるテンプレートとして使用されます。どのオブジェクトもそれ独自のプロパティを指定できます。オブジェクト作成時にも実行時にも可能です。さらに、どのオブジェクトも別のオブジェクトに対するプロトタイプとして関連付けることができます。2 つ目のオブジェクトが 1 つ目のオブジェクトのプロトタイプを共有するということもできます。

クラスの定義

クラスベース言語ではクラス定義ごとにクラスを定義します。定義では特殊なメソッドを指定してそのクラスのインスタンスを作成することができます。そのようなメソッドはコンストラクタと呼びます。コンストラクタメソッドはインスタンスのプロパティに対する初期値を指定することができます。また、作成時に他の適当な処理を実行することもできます。new 演算子をコンストラクタメソッドと一緒に用いることでクラスのインスタンスを作成できます。

JavaScript は同様のモデルに従っていますが、コンストラクタと別になっているクラス定義がありません。その代わりに、プロパティと値からなる特定の初期的なセットを持つオブジェクトを作成するコンストラクタ関数を定義します。どの JavaScript 関数もコンストラクタとして使用できます。new 演算子をコンストラクタ関数とともに使用することで新しいオブジェクトを作成します。

サブクラスと継承

クラスベース言語ではクラス定義を通じてクラスの階層を作ります。クラス定義では新しいクラスがある既存のクラスのサブクラスになるように指定することができます。サブクラスはスーパークラスの全プロパティを継承します。さらに新しくプロパティを追加したり継承したものを変更することもできます。例えば、Employee クラスが name および dept プロパティのみを含んでおり、Manager は reports プロパティを追加する Employee のサブクラスであるとします。この場合、Manager クラスのインスタンスは name、dept、reports という 3 つのプロパティをすべて持つことになります。

JavaScript では、原型的なオブジェクトをどのコンストラクタ関数にも結びつけることができるようにして継承を実装しています。そのため、全く同じような Employee と Manager の例を作成することができますが、使用する用語が若干異なります。まず、Employee コンストラクタ関数を定義します。これは name および dept プロパティを指定します。次に Manager コンストラクタ関数を定義します。これは reports プロパティを指定します。最後に新しい Employee オブジェクトを Manager コンストラクタ関数に対するプロトタイプとして代入します。そして新しい Manager を作成すると、このオブジェクトは Employee オブジェクトから name および dept プロパティを継承します。

プロパティの追加と削除

クラスベース言語では一般的にクラスをコンパイル時に生成し、コンパイル時または実行時にクラスのインスタンスを作成します。クラス定義後にそのクラスのプロパティの数や型を変更することはできません。しかし、JavaScript ではどんなオブジェクトでも実行時にプロパティを追加したり削除したりすることができます。あるオブジェクトのセットでプロトタイプとして使用されているオブジェクトにプロパティを追加すると、そのプロトタイプの使用元であるオブジェクトにも新しいプロパティが追加されます。

違いの概要

次の表でこれらの違いをいくつか短くまとめてみます。この章の残りで、JavaScript のコンストラクタとプロトタイプを用いてオブジェクト階層を作成することについての詳細を説明していきます。また、この方法が Java ではどう変わるかという比較もします。

クラスベース (Java) プロトタイプベース (JavaScript)
クラスとインスタンスは異なる実体である。 すべてのオブジェクトはインスタンスである。
クラス定義を用いてクラスを定義する。また、コンストラクタメソッドを用いてクラスをインスタンス化する。 コンストラクタ関数を用いてオブジェクトのセットを定義し、作成する。
new 演算子を用いて単一のオブジェクトを作成する。 同じ。
既存のクラスのサブクラスを定義するクラス定義を用いてオブジェクト階層を構築する。 コンストラクタ関数に結びつけられたプロトタイプとしてオブジェクトを代入することでオブジェクト階層を構築する。
クラスチェーンに従ってプロパティを継承する。 プロトタイプチェーンに従ってプロパティを継承する。
クラス定義がクラスの全インスタンスの全プロパティを指定する。実行時に動的にプロパティを追加することはできない。 コンストラクタ関数またはプロトタイプがプロパティの初期セットを指定する。個々のオブジェクトやオブジェクトの全体のセットに動的にプロパティを追加したり、それらからプロパティを除去したりできる。

문서 태그 및 공헌자

 최종 변경: teoli,