prototype継承、コンストラクタ、クラス継承、あしたやるやつ

インスタンスとプロトタイプ継承

問題

  1. 静的コンストラクタを作れ
  2. 静的コンストラクタからのインスタンスに動的メソッドを追加せよ
  3. 動的なメソッドを追加しても他のインスタンスからは参照できないことを証明せよ(同一のコンストラクタから派生したインスタンスであってもそれぞれが持つメンバは同一とは限らない)
  4. インスタンスにプロトタイプ参照できるメソッドを追加せよ
  5. メンバの追加や変更がリアルタイムに認識できることを証明せよ
  6. インスタンスのプロパティに値を設定しても他のインスタンスは影響を受けないことを確認できる記述せよ(プロトタイプの隠蔽)
  7. 静的メソッドとプロパティで定義したものをインスタンス生成して呼び出してエラーになることを確認せよ
  8. delete演算子を使ってインスタンスプロパティを削除せよ()
  9. オブジェクトリテラルでプロトタイプを定義せよ

※プロパティの宣言→コンストラクタで。メソッドの宣言→プロトタイプで。

  • 静的プロパティ/静的メソッド→インスタンスを生成しなくても呼び出せるプロパティ・メソッド
  • インスタンスメソッド/インスタンスプロパティ→インスタンスから暗黙的に参照されることを目的としたメソッド・プロパティ
  • 静的メソッドに定義したものをインスタンスメソッドとして呼び出してもエラーになる
  • 静的プロパティは読み取り専用。静的メソッドの中ではthisキーワードは使えない
  • なぜ静的メンバを定義するのか。グローバル関数、変数は競合するから。グローバル変数versionと静的メンバArea.versionは別物。関連する機能や情報は静的メンバにまとめること
  • delete演算子はプロトタイプまで遡ってプロパティを削除しない。インスタンス側で追加、削除されたものがプロトタイプで遡って影響を与えない
  • もしプロトタイプで定義されたメンバをインスタンス単位で削除したい場合擬似的にundefinedを代入する。ただ厳密には擬似的で、削除されていないのでfor inループでは以前存在する
  • オブジェクトリテラルを利用することで「Member.prototype.~」というような記述が最小限に抑えられる。結果、オブジェクト名に変更があった場合にも影響箇所を限定できる。コードの可読性が増す

オブジェクトの継承(差分プログラミング)

  • オブジェクトのプロトタイプとしてインスタンスをセット、継承する
  • 継承関係は動的に変更可能

問題

  • javascriptのプロトタイプチェーンは、インスタンスが生成された時点で固定され、その後の変更にかかわらず保存されることを証明せよ

[javascript]
function initializeBase(derive,base,baseArgs){
base.apply(derive,baseArgs);
for(prop in base.prototype){
var proto = derive.constructor.prototype;
if(!proto[prop]){
proto[prop] = base.prototype[prop];
}
}
}
var Member = function(firstName,lastName){
this.firstName = firstName;
this.lastName = lastName;
};
Member.prototype.getName = function(){
return this.lastName + '' + this.firstName;
};

var SpecialMember = function(firstName,lastName,role){
initializeBase(this,Member,[firstName,lastName]);
this.role = role;
}
SpecialMember.prototype.isAdministrator = function(){
return (this.role == 'Adoministrator');
};
var mem = new SpecialMember('賢二','森田','Adoministrator');
document.write('名前:' + mem.getName()); //森田賢二
document.write('管理者' + mem.isAdministrator()); //true
[/javascript]