プロが教える店舗&オフィスのセキュリティ対策術

後学のため、JavaScriptについて勉強しています。

JavaScriptでもクラス(のようなもの)を定義してオブジェクトを作成できるようですが、サブクラスを定義する方法が分かりません。メソッドやコンストラクタはどのように継承すればよいのでしょうか。

お分かりの方おられましたら、ご教授のほどお願い致します。

A 回答 (3件)

JavaScriptにはクラス定義がないので、プロパティとメソッドを動的に継承しなければなりません。



プロパティは、コンストラクタから親のコンストラクタを呼び出すことで継承します。
ただし、その際 this のメソッドとして呼ばないと、親コンストラクタでの初期化が自分に反映されません。親コンストラクタをメソッドとして呼び出すには、
> call(または apply)メソッドを使い、「親コンストラクタ.call(this, 引数...)」とする。
または
> 一時的に親のコンストラクタをプロパティに登録し、実行後に削除する。
という方法を取ります。

メソッドは、親の prototype を自分の prototype にコピーすることで継承します。
ただし、prototype はオブジェクトなので単に代入すると親のものを参照するようになってしまい、メソッドの追加などが親にも影響してしまいます。この問題の解法としては、
> for - in で prototype のプロパティを1つ1つコピーする。
とか
> 親のインスタンスを作り、それを prototype に代入する。
というような方法が知られています。

しかし、for - in ではビルトインオブジェクトなどが持つ内部プロパティまでは取れないので、汎用的な継承の手段としては今ひとつです。
また、親のインスタンスを使う方法には余計な親コンストラクタ呼び出しが伴うので、親コンストラクタでクラスプロパティの変更などをしていると問題が生じます。

この問題を回避するには、親クラスと同じ prototype を持ち、コンストラクタでは何もしないダミークラスを定義して、そのインスタンスを prototype として使うようにします。

例:Base クラスを継承して Deriv クラスを構築する。

/**** class Base ****/

// コンストラクタ
function Base(a) {
  ++Base.count;    // 生成したBaseオブジェクトをカウント(親クラスを直接使って継承すると、問題が起こる例)
  this.a = a;
}

// メソッド定義
Base.prototype.print = function () {
  document.write("a=",this.a, "<br>");
}

/**** class Deriv ****/

// コンストラクタ
function Deriv(a, b) {
  // プロパティの継承
  Base.call(this, a);

  // 固有プロパティの追加
  this.b = b;
}

// メソッドの継承
function DerivPrototype() {}            // 継承用ダミークラス
DerivPrototype.prototype = Base.prototype;  // プロトタイプは代入でOK
Deriv.prototype = new DerivPrototype;
Deriv.prototype.constructor = Deriv;      // コンストラクタまで変更されてしまうので修正

// メソッド定義
Deriv.prototype.print = function () {       // print のオーバーライド
  document.write("a=",this.a, ", b=",this.b, "<br>");
}

このコードで気になるのは、メソッド継承の部分だけ抽象レベルが低いことでしょう。単に関数化するだけでも見通しは良くなりますが、次のように全ての関数の上位クラスである Function のメソッドとして登録すると、さらに可読性が高まります。

Function.prototype.inherit = function (baseClass) {
  function tempClass() {}
  tempClass.prototype = baseClass.prototype;
  this.prototype = new tempClass;
  this.prototype.constructor = this;
}

このコードをクラス定義の前に記述しておき、継承の部分は次のように変更します。

Deriv.inherit(Base);

※インデントなどに全角空白を使っているので、コピーする場合はタブなどに置換して下さい。
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
詳細な解説とサンプルのおかげで、問題点なども含めた非常に深い知識と、大変高度なテクニックを学ぶことができました。
どうもありがとうございました。

お礼日時:2005/09/02 02:14

こんな感じ


-------------------------------------------------------------
//Animalクラス
//コンストラクタ
function Animal(name, kind){
this.name=name;
this.kind=kind;
}
//メソッド
Animal.prototype.hey=function(){
return "I'm a " + this.name;
};
Animal.prototype.toString=function(){
return "{" + this.name + " of " + this.kind +"}";
};
//Catクラス/Animalサブクラス
function Cat(name){
this.name=name;
this.kind="CAT";
}
Cat.prototype=new Animal("","");//継承にあたる
Cat.prototype.constructor=Cat;//コンストラクタは自分のを使う

//新しいメソッド
Cat.prototype.sing=function(){
return "nya-o";
};
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
分かりやすいサンプルにより、JavaScriptでのクラスの理解が一層深まりました。
どうもありがとうございました。

お礼日時:2005/09/02 02:14

こんにちは、じゃんぬねっと です。



子Class.prototype = new 親Class;

http://www.parkcity.ne.jp/~chaichan/src/javascne …
    • good
    • 0
この回答へのお礼

ご回答ありがとうございます。
提示して頂いたURLなど、大変参考になりました。
どうもありがとうございました。

お礼日時:2005/09/02 02:14

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!