The Wayback Machine - http://web.archive.org/web/20060428053254/http://www.interq.or.jp:80/student/exeal/dss/ejs/3/2.html

本文へジャンプ

トップ > Effective JavaScript > 3 オブジェクト > 3.2 コンストラクタとプロトタイプ

3.2 コンストラクタとプロトタイプ

前節ではオブジェクトを作成して使う方法について述べました。あるオブジェクトについてこのような立場をとる人間、オブジェクトをクライアントといいます。クライアントは「顧客」とか「依頼人」という意味です。つまりオブジェクトから見れば「お客」なのです。それ故オブジェクトはクライアントを中心に振舞わなければなりませんし、クライアントとの契約が守れないときはそれなりの対処をしなければいけません (「2. 例外」を参照)

この節で解説するのはオブジェクトを定義する方法です。JavaScript についてよく知らない多言語プログラマは「JavaScript はオブジェクトのクライアントとしてはまあまあだが、クラスを定義できないから駄目だ」と言うかもしれません。確かに JavaScript にはクラスを定義するための構文が存在しません。しかしそれは言語が貧弱だからではなく、JavaScript がクラスベースではなくプロトタイプベースの設計を選んだからです (JavaScript 2.0 ではクラスが使えますが)。プロトタイプ理論に従えば「オブジェクトを継承」させることも可能なのです。クライアントの前で仕事をするのはクラスではなくオブジェクトであることを忘れないで下さい

コンストラクタの定義


new 使 () [[Construct]] (ECMAScript 3rd Edition 13.2.2 [[Construct]] )


(一)[[Class]] "Object" 

(二) prototype [[Prototype]] Object::prototype 使

(三)[[Call]][[Construct]]使使 this 使

(四)[[Call]]
 

3 this 
 

function MyObject() {
  this; // 作成されたオブジェクト
}
     

 (4)
 

var obj = new MyObject;
obj; // 作成されたオブジェクト
     



()32 this 
 

function MyObject(n) {
  this.myProperty = n; // プロパティ
}

var obj = new MyObject(7);
obj.myProperty; // 7
     

1. 使

メソッドの定義



 

function MyObject() {
  this.myMethod = function() {
  };
}

var obj = new MyObject();
obj.myMethod(); // 呼び出す
     

 JavaScript 
 

var str = new String();
str.concat;                   // concat オブジェクト
str.hasOwnProperty("concat"); // false
     

 String  concat  ()  String::prototype 
 

String.prototype.hasOwnProperty("concat"); // true
     

 MyObject 
 

function MyObject() {
  MyObject.prototype.myMethod = function() {
  };
  // 或いは次でも可
  this.constructor.prototype.myMethod = function() {
  };
}
     

11

function MyObject() {
}

MyObject.prototype.myMethod = function() {
};
					

プロトタイプ


 (prototype) 1使 ( prototype ) 

 ( MyObject.prototype) [[Prototype]] (JavaScript 1.3  __proto__ ) myMethod 


(一)調 ()

(二) ( MyObject.prototype.myMethod )

(三)

(四)[[Prototype]] null 
 

  (prototype chain) 使辿


 

// コンストラクタ
function Person(nAge) {
  this.m_nAge = nAge;
}

// 年齢を返すメソッド
Person.prototype.getAge = function() {
  return this.m_nAge;
};

var Don = new Person(22);   // 勿論これは冗談
var Exeal = new Person(21);

Don.getAge == Exeal.getAge; // true
Don.getAge();               // 22
     

2 Don  getAge  Don  Person::prototype (= Don.__proto__) 

クラスメンバ

クラスメンバ (静的メンバ) はインスタンス毎に与えられるメンバではなくクラス毎に存在するメンバです。JavaScript にはクラスが無いのでコンストラクタメンバとでも呼ぶことにしましょう。コンストラクタメンバは特定のインスタンスが無くても存在可能なメンバで constructor プロパティもこれに該当します

コンストラクタメンバの定義方法は非常に簡単です。コンストラクタにプロパティを設定するだけです


// コンストラクタ
function Person(nAge) {
  this.m_nAge = nAge;
  if(Person.m_nPopulation != undefined)
    ++Person.m_nPopulation;
}

Person.m_nPopulation = 0;

var Don = new Person(22);
var Exeal = new Person(21);

Person.m_nPopulation; // 2
Don.m_nPopulation;    // 残念ながらこれは駄目
					

継承


 JavaScript 

 D B  (inheritance)  D D B  


 

function Person(nAge) {
  this.m_nAge = nAge;
}

Person.prototype.getAge = function() {
  return this.m_nAge;
};

function Programmer(nAge, strProject) {
  /* Person メンバの継承を実現するコード */
}

var Exeal = new Programmer(21, "EJS");
Exeal.getAge();
     


 

function Person(nAge) {
  this.m_nAge = nAge;
}

function Programmer(nAge, strProject) {
  this.m_nAge = nAge;             // 真似する
  this.m_strProject = strProject; // 新しく追加するプロパティ
}
     

2 Person  Programmer 

(JavaScript )  Programmer 鹿 Person  Programmer  Person  Programmer  Person  Person 2
 

// 1つ目
function Programmer(nAge, strProject) {
  this.__super = Person;         // 新インスタンスを介して
  this.__super(nAge);            // 継承元コンストラクタを呼ぶ
  this.constructor = Programmer; // コンストラクタが Person にセットされるので元に戻す
  delete this.__super;
  /* Programmer コンストラクタの処理 */
}

// 2つ目
function Programmer(nAge, strProject) {
  Person.call(this, nAge);
  this.constructor = Programmer;
  /* Programmer コンストラクタの処理 */
}
     

2 ECMAScript 3rd Edition 使

 Person.prototype  Programmer.prototype 
 

/*
 *  コンストラクタの定義...
 */

Programmer.prototype = Person.prototype;

Programmer.prototype.getProjectName = function() {
  return this.m_strProject;
};

var Exeal = new Person(21);
Exeal.getProjectName; // undefined でない!
     

Programmer.prototype  Person.prototype  Person 

使辿Programmer Person  Programmer  Person JavaScript 
 

Programmer.prototype.__proto__ = Person.prototype;
     

 ECMAScript 使
 

Programmer.prototype = new Person();
     




(一)Person Programmer 

(二)Person  Person 

(三)Programmer.prototype  Person 

(四)Programmer  Person 
 


 

Programmer.prototype = new Person();

var Exeal = new Programmer(21, "EJS");
Exeal.getAge();          // 21
Exeal.getProjectName();  // "EJS"
Exeal instanceof Person; // true
     

使 m_nPopulation 1



 JavaScript 2

多重継承


1

便使 ()  Java  JavaScript  1

オーバーライド


 Person 
 

function Person() {
}

// 眠る
Person.prototype.sleep = function() {
  this.goToBed();
};
     

 Person  Programmer  Programmer  sleep 使Programmer  Progammer.prototype 
 

function Person() {
}

Person.prototype = new Person();

// 眠る
Programmer.prototype.sleep = function() {
  this.relaxOnYourChair();
};
     

 Programmer  sleep  Programmer.prototype.sleep   

 Function::apply  Function::call 使
 

var Exeal = new Programmer();

// 今日はベッドで眠れそう
Person.prototype.sleep.call(Exeal);
     

 Programmer  Person Java  super  ECMAScript 


残りの話題

JScript 、JavaScript 、ECMAScript におけるオブジェクト指向のオフィシャルな (?) 話題は以上のようなものです。JavaScript のメンバの種類、コンストラクタとプロトタイプ、プロトタイプチェインによる継承が可能になりました。これらを習得したことで (習得して頂けましたね?) あなたは JavaScript のオブジェクトを自由に操り、仕事をさせることができます。次節からは更にオブジェクトの実装側のテクニックを取り上げていくことにします

Valid XHTML 1.1! © 1999-2003 exeal <Edit this page>