Javascriptオブジェクト指向プログラミング(三)非構造関数の継承

2958 ワード

今日は最後の部分です.構造関数を使わずに「継承」することを紹介します.
一、何が「非構造関数」の継承ですか?例えば、今は「中国人」という対象があります.
 
  
  var Chinese = {
    nation:' '
  };
もう一つの相手は「医者」です.
 
  
  var Doctor ={
    career:' '
  }
すみません、どうやって「医者」に「中国人」を継承させることができますか?つまり、私はどうやって「中国人医師」の対象を作ることができますか?
ここで注意したいのですが、この二つのオブジェクトは普通のオブジェクトで、コンストラクタではなく、コンストラクター法を使って「継承」ができません.
二、object()方法json形式の発明者Duglas Crockfordは、object()関数を提案しています.これができます.
 
  
  function object(o) {
    function F() {}
    F.prototype = o;
    return new F();
  }
このobject関数は、実は一つのことしかしません.子の対象となるプロトタイプの属性を父の対象に向けて、子の対象を父の対象とつなげます.
使用する場合は、最初のステップは親のオブジェクトに基づいて、サブオブジェクトを生成します.
var Doctor=object(Chinese);
そして、サブオブジェクト自体の属性を追加します.
ドクター.or.carer='医者'
このとき、子オブジェクトは既に親オブジェクトの属性を引き継いでいます.
alert(Doctor.nation)//中国
三、浅いコピーは「プロトタイプチェーン」を使う以外に、もう一つの考えがあります.父の対象の属性を全部子供の対象にコピーしても、継承が可能です.
下のこの関数はコピーをしています.
 
  
  function extendCopy(p) {
    var c = {};
    for (var i in p) {
      c[i] = p[i];
    }
    c.uber = p;
    return c;
  }
使う時は、こう書きます.
 
  
  var Doctor = extendCopy(Chinese);
  Doctor.career = ' ';
  alert(Doctor.nation); //
しかし、このようなコピーには問題があります.それは、親オブジェクトの属性が配列または他のオブジェクトに等しい場合、実際には、子オブジェクトが取得するのはメモリアドレスだけで、本物のコピーではなく、親オブジェクトが改竄される可能性があります.
今からChineseに「出生地」の属性を追加します.その値は配列です.
Chinese.birthPlaces=[北京],[上海],[香港];
extendCopy関数により、DoctorはChineseを継承しました.
var Doctor=extedCopy(Chinese)
そして、私たちはDoctorの「出生地」に都市を追加します.
Doctor.birthPlaces.push('厦門')
何が起きましたか?Chineseの「生誕地」も改変されました.
alert(Doctor.birthPlaces)//北京、上海、香港、アモイ
alert(Chinese.birthPlaces)//北京、上海、香港、アモイ
だから、extendCopyは基本的なタイプのデータをコピーするだけです.私たちはこのコピーを「薄いコピー」と言います.これは初期のjQueryの継承方式です.
四、ディープコピーとは、真の意味での配列と対象のコピーを実現することである.その実現は難しくないです.再帰的に「薄いコピー」を呼べばいいです.
 
  
  function deepCopy(p, c) {
    var c = c || {};
    for (var i in p) {
      if (typeof p[i] === 'object') {
        c[i] = (p[i].constructor === Array) ? [] : {};
        deepCopy(p[i], c[i]);
      } else {
         c[i] = p[i];
      }
    }
    return c;
  }
使う時はこう書きます.
var Doctor=deepCopy(Chinese)
現在、親オブジェクトに属性を付けます.値は行列です.この属性をサブオブジェクトに変更します.
 
  
  Chinese.birthPlaces = [' ',' ',' '];
  Doctor.birthPlaces.push(' ');
この時、父の対象は影響を受けません.
 
  
  alert(Doctor.birthPlaces); // , , ,
  alert(Chinese.birthPlaces); // , ,
現在、jQuery庫で使われているのはこのような継承方法です.
(終わり)