サイ本要約 9章後半

9章の後半から!


9.6 継承以外のクラス拡張方法


別クラスから関数を「借りる」

  • 別クラスのメソッドをコピーして使用することができる。
  • コピー元prototype -> コピー先prototype へとメソッドをコピーしたり。


メソッドコピー関数の例

  • あるクラスの全メソッドを、別のクラスのプロトタイプオブジェクトにコピーする関数の例。

function borrowMethods(borrowFrom, addTo) {
  //コピー元
  var from = borrowFrom.prototype;
  //コピー先
  var to   = addTo.prototype;
  
  //コピー元プロトタイプの全プロパティを調べる
  for(m in from) {
    //関数以外は無視する
    if (typeof from[m] != "function") continue;
    //メソッドのコピー
    to[m] = from[m];
  }
}


ミックスインクラス

  • 他のクラスから利用することを想定した、汎用的なメソッドを定義するクラスのこと。
  • 例:Utilにfooメソッドを定義して、他で使う。

//汎用クラス
function Util() {}
Util.prototype.foo = function(x) {
  alert(x);
}

//使用元クラス
function Hoge() {
  .
  .
}
function Fuga() {
  .
  .
}
//直接引っ張ってきたり
Hoge.prototype.foo = Util.prototype.foo;
//↑で定義したborrowMethods使用したり
borrowMethods(Util, Fuga);

//使ってみる
var hoge = new Hoge();
hoge.foo(3);  //alert(3)
var fuga = new Fuga();
fuga.foo(4);  //alert(4)

  • コンストラクタ関数を借りる例

//汎用クラス
function Util(num) { this.num = num; }
Util.prototype.getNum = function() {
  return this.num;
}

//使用元クラス
function Hoge(num) {
  .
  .
  //コンストラクタを借りる
  Util.call(this, num)
}
//メソッドも
Hoge.prototype.getNum = Util.prototype.getNum;

//使ってみる
var h = new Hoge(193);
h.getNum(); //193


9.7 オブジェクトクラスの判定


typeof演算子

  • 基本データ型とオブジェクトの区別には便利だとか
  • typeof null は"object"
  • 関数もオブジェクトなのに、返り値は"function"
x typeof x
数値 "number"
文字列 "string"
論理値 "boolean"
オブジェクト "object"
配列 "object"
関数 "function"
null "object"
undefined "undefined"


instanceof演算子

  • 左側のオペランドがオブジェクトでない場合false
  • 右側のオペランドがオブジェクトでない場合、実行時エラー
  • 関数fに対して以下の式はすべてtrue

typeof f == "function"
f instanceof Function
f instanceof Object

  • あるオブジェクトがとあるクラスの直接のインスタンスであるかどうかは、constructorプロパティを使う。

var d = new Date();
d instanceof Object     //true
d.constructor == Object //false
d.constructor == Date   //true



Object.toString()

  • デフォルトのObject.toString()の返り値は、"[object (class名)]"
  • (class名)は、オブジェクトの内部クラスを意味する文字列。
  • ユーザ定義オブジェクトでは常に(class名)は"Object"なので、ユーザ定義クラスの判定に使える?
  • ほとんどのクラスはtoString()をオーバーライドしているので、あるオブジェクトに対してObject.toString()を呼び出したい場合は、以下のようにする。

Object.prototype.toString.apply(hogeObject);

//配列での例
[1,2].toString(); //"1,2"
Object.prototype.toString.apply([1,2]); //"[object Array]"


ダックタイピング

  • 「あるオブジェクト(O)が、あるクラス(C)で定義されているメソッドをすべて実装していれば、OはCのインスタンスであるとみなせる」
  • ダックタイピングができるメリットがちゃんとわかっていない。おしえてエロい人!


9.8 例:defineClass()ユーティリティ

  • 9章で出てきたことを使った例なので、目を通しておこう!決してめんどくさくなったわけじゃないよ!