JavaScript と 継承 2
OOP と JavaScript における継承について、JavaScript と継承 の続きです。
__proto__ プロパティ
Netscape Navigator 4.x 及び Netscape 6 では オブジェクトの __proto__ プロパティにより、オブジェクトのプロトタイプを確認できます。例を以下に示します。
※ __proto__ プロパティは Internet Explorer ではサポートされていません。
function Shape() {
this.borderWidth = 5;
}
function Square() {
this.edge = 12;
}
// Squeare のプロトタイプとして Shape を呼出す
Square.prototype = new Shape;
// Square のインスタンス生成
myPicture = new Square;
// myPicture のプロトタイププロパティを確認
alert(myPicture.__proto__);
// スーパークラスから継承したプロパティが呼出される
alert(myPicture.borderWidth);
///// 5この例において、ローカル変数で定義されていないプロパティ boderWidth が呼出されると、__proto__ プロパティがプロパティを探すオブジェクト ( この場合 Shape) を指示します。また、以下の例のように、オブジェクトの、__proto__ プロパティを次々とたどることができます。
function Language(){};
function English(){};
English.prototype = new Language;
function Alphabet(){};
Alphabet.prototype = new English;
newCharacter = new Alphabet();
alert(newCharacter.__proto__ == Alphabet.prototype);
///// true
alert(newCharacter.__proto__.__proto__ == English.prototype);
///// true
alert(newCharacter.__proto__.__proto__.__proto__ == Language.prototype);
//trueinstanceOf メソッドの実装
__proto__ プロパティが利用できる NS では、以下のように、オブジェクトが特定のコンストラクタから生成されたインスタンスかを調べる instanceOf メソッドを定義できます。// オブジェクトがコンストラクタのインスタンスかどうかを調べる関数これを前出の例に適用してみます。newCharacter は Alphabet, English, Language の全てのインスタンスですから、この関数を適用すると以下のようになります。
// object, constructorName: コンストラクタ名
function instanceOf(object, constructorName) {
while (object != null) {
if (object == constructorName.prototype) return true;
object = object.__proto__;
}
return false;
}
alert(instanceOf(newCharacter, Alphabet));
///// true
alert(instanceOf(newCharacter, English));
///// true
alert(instanceOf(newCharacter, Language));
///// true
for...in
オブジェクトのプロパティ名は、for (プロパティ in オブジェクト名)で参照できます。コンストラクタ employee により生成された newPerson オブジェクトのプロパティ名は以下のように得られます。
function employee() {
this.dept = "HR";
this.manager = "John Johnson";
}
function printProp() {
var newPerson = new employee();
// ken オブジェクトのプロパティを順に表示
for (property in newPerson) {
alert(property);
}
}
printProp();
///// dept
///// manager 以下のように Employee のスーパークラス Person を定義し、Employee のプロトタイプとした場合に、オブジェクトのスーパークラスのプロパティもたどるのか試してみます。function Person(){
this.animal = 'human';
}
function Employee() {
this.dept = 'HR';
this.manager = 'John Johnson';
}
Employee.prototype = new Person;
function printProp3() {
var Ken = new Employee();
for(prop in Ken) alert(prop);
}
printProp3();
///// dept
///// manager
///// animal これより、for...in では、オブジェクトのスーパークラスのプロパティもたどることが分かりました。あるオブジェクトに指定したプロパティが存在するかどうかをチェックするには、hasOwnProperty, や propertyIsEnumerable メソッドを使います。
上記の例に続く以下の例を見てみます。
参考: Object-Oriented Programming with JavaScript, Part I: Inheritance
Ken = new Employee();
// dept プロパティを持つかチェック
alert(Ken.hasOwnProperty('dept'));
///// true
// name プロパティを持つかチェック
alert(Ken.hasOwnProperty('name'));
///// false
Ken.children = new Array('taro', 'sara');
// 0 番目の要素があるか
alert(Ken.children.propertyIsEnumerable(0));
///// true
// children は 3 番目の要素があるか
alert(Ken.children.propertyIsEnumerable(3));
///// false
