クラスの作り方

クラスを定義

空のコンストラクタ

 var Person = function() {};

コンストラクタでメソッドやフィールドを定義

thisを使ってクラスのプロパティにアクセスする。

 var Person = function(name) {
     this.name = name;
     this.say = function() { alert("hello, " + this.name); };
 };

ただし、この方法はインスタンス生成ごとにメソッドを定義する事になり、メモリ効率が悪い。これを避けるには、プロトタイプによるメソッドやフィールドを定義を行う。

クラスからインスタンスを生成

 var person = new Person("taro");
 person.say();

クラスにプロトタイプでメソッドやフィールドを定義

 Person.prototype = {
     say2: function() {
         alert("hello2, " + this.name);
     }
 };
 person.say2();

プロトタイプ汚染

この方法でArrayのような組込みクラスを拡張する事が可能だが、安易に拡張するとfor inでオブジェクトのプロパティを列挙すると拡張したプロパティ(メソッド)と元のプロパティ(メソッド)が混ざってしまう(プロトタイプ汚染)ので注意が必要。

クラスの継承

親クラス作成

 var Person = function(name) { this.name = name; }; 
 Person.prototype = { say: function() { alert("hello, " + this.name) } };

子クラス作成

 var Man = function(name) { this.name = "Mr." + name; };

親クラスを継承

 Man.prototype = new Person;
 var m = new Man("taro");
 m.say();

プロトタイプチェイン

メソッドの検索は次の順で行われる。

  • m.say()
  • Man.prototype.say()
  • Person.prototype.say()
  • Object.prototype.say()

親クラスを辿って行き、最終的にObject.prototypeで見つからなければ、終了する。

プロトタイプ継承の注意点

なお、継承のために、

 Man.prototype = new Person;

ではなく、

 Man.prototype = Peroson.prototype;

としてはならない。この場合、ManのprototypeはPersonのprototypeを参照する事になるので、

 Man.prototype.say2 = function () { alert('hello2') };

のようにManにメソッドを追加すると、Personにもメソッドが追加されてしまう。

 var p = new Person();
 p.say2(); // 本来、未定義であるべき

JavaScriptのクラス(オブジェクト)の問題点

  • 親クラスのコンストラクタ(メソッド)を呼び出すのが難しい。
  • 多重継承が難しい。 これらを解決するには、何らかのライブラリを使うのが妥当。

参考

Defining classes and inheritance
http://prototypejs.org/learn/class-inheritance
A Base Class for JavaScript Inheritance
http://dean.edwards.name/weblog/2006/03/base/
Simple JavaScript Inheritance
http://ejohn.org/blog/simple-javascript-inheritance/

トップ   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS