- バックアップ一覧
- 差分 を表示
- 現在との差分 を表示
- ソース を表示
- JavaScript/OOP/クラスの作り方/関数オブジェクトを使ったクラス作成 - 応用 へ行く。
- 1 (2009-06-07 (日) 12:09:53)
- 2 (2009-10-10 (土) 18:07:01)
- 3 (2009-11-09 (月) 12:07:31)
- 4 (2009-11-09 (月) 16:42:49)
- 5 (2011-01-26 (水) 21:42:21)
- 6 (2011-07-14 (木) 20:20:16)
- 7 (2011-07-15 (金) 14:49:59)
- 8 (2011-07-26 (火) 02:26:48)
- 9 (2012-02-13 (月) 06:48:17)
- 10 (2012-07-24 (火) 16:14:12)
- 11 (2012-07-28 (土) 06:55:52)
クラス(オブジェクト)の作り方
オブジェクトを生成
var obj = new Object(); obj.name = 'taro'; obj.say = function () { alert("hello, " + this.name); };
を省略して、オブジェクトリテラルで書くと、
var obj = { name : "taro", say : function() { alert("hello, " + this.name); } };
クラスを定義
空のコンストラクタ
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のクラス(オブジェクト)の問題点
- 親クラスのコンストラクタ(メソッド)を呼び出すのが難しい。
- 多重継承が難しい。 これらを解決するには、何らかのライブラリを使うのが妥当。
Prototype.jsを使って継承
var Woman = Class.create(); // クラス定義 Object.extend(Woman.prototype, Person.prototype); // 継承 Object.extend(Woman.prototype,{ // メソッドのオーバーライド initialize: function(name) { this.name = "Miss." + name; } }); var w = new Woman("hanako"); w.say();