1. 程式人生 > >面向對象 ( OO ) 的程序設計——繼承

面向對象 ( OO ) 的程序設計——繼承

效果 cal tor tro prot false ret als 其中

僅支持實現繼承,且主要依靠原型鏈來實現,不過一般會混合構造函數一起實現繼承

1 原型鏈

    • 繼承使用原型鏈進行傳遞,類似指針一層層向上指向對應原型,構成鏈狀

    • 在使用原型鏈近似實現繼承時,實例中的所有屬性和方法都會被繼承

       1 // 第一個類型
       2 function Func1(){
       3     this.property = true;
       4 }   
       5 // 第一個類型的方法
       6 Func1.prototype.getFunc1Value = function(){
       7     return this.property;
       8 };
       9 
      10 // 第二個類型
      11 function
      Func2(){ 12 this.func2property = false; 13 } 14 15 // 第一個類型的實例賦給 Func2.prototype,實現繼承 ( 替換原型 ) 16 Func2.prototype = new Func1(); 17 18 // 為第二個類型增加了新方法 19 Func2.prototype.getFunc2Value = function(){ 20 return this.func2property; 21 }; 22 23 // 為第二個對象創建實例 24 var out = new Func2(); 25 26 // 利用該實例訪問第一個對象方法、屬性及第二個對象的方法、屬性
      27 console.log(out.getFunc1Value()); 28 console.log(out.property); 29 console.log(out.getFunc2Value()); 30 console.log(out.func2property);

      繼承實質為將父對象的替換為子對象的原型

      添加新方法或重寫,均要放在替換原型語句後面重寫是覆蓋掉,原先的還在,子對象實例訪問到的是重寫的,父對象實例訪問的是原先的方法

    • A 是 B 的實例

      A instanceof B;         //返回 true 或 false
    • A 是原型

      A.prototype.isProptotypeOf(instance);           //
      返回 true 或 false

2 借用構造函數

使用 call() 或 apply() 方法借用超類型 ( 父對象 ) 的構造函數

 1 // 構造函數1
 2 function Func1(){
 3     this.colors = ["red","blue","green"];
 4 }
 5 
 6 // 構造函數2
 7 function Func2(){
 8     // 借用構造函數1
 9     Func1.call(this);
10 }
11 
12 // 創建實例
13 var out2 = new Func2();
14 out2.colors.push("black");  // 為構造函數2的實例增加一個值
15 var out1 = new Func1();
16 
17 // 輸出可知每次新建實例均借用構造函數1,值不變
18 console.log(out1.colors);
19 console.log(out2.colors);
20 }

效果如下

技術分享

3 傳遞參數

借用構造函數可以在子類型構造函數中向超類型構造函數傳遞參數

 1 // 構造函數1
 2 function Func1(name){
 3     this.name = name;
 4 }
 5 
 6 // 構造函數2
 7 function Func2(){
 8     // 借用構造函數1
 9     Func1.call(this,"Cherry");
10     this.age = 21;
11 }
12 
13 // 創建實例
14 var out2 = new Func2();
15 
16 console.log(out2.name);
17 console.log(out2.age);

技術分享

4 組合繼承

將原型鏈和借用構造函數技術組合到一塊,發揮二者之長。實質為使用原型鏈實現對原型屬性和方法的繼承,通過借用構造函數實現對實例屬性的繼承

組合繼承是最常用的繼承方法

5 寄生組合式繼承

盡管組合繼承已經十分好用了,但是由於會兩次調用父類型的構造函數,導致效率較低,故提出了寄生組合式繼承,僅調用一次父類型的構造函數,提高效率,是實現基於繼承的最有效方式

示例:

 1 function inheritPrototype(subType, superType) {
 2     var prototype = superType.prototype;
 3     prototype.constructor = subType;
 4     subType.prototype = prototype;
 5 }
 6 
 7 function SuperType(name) {
 8     this.name = name;
 9     colors = ["red", "blue", "green"];
10 }
11 
12 SuperType.prototype.sayName = function () {
13     var out1 = document.getElementById("out1");
14     var p = document.createElement("p");
15     p.innerHTML = this.name;
16     out1.appendChild(p);
17 };
18 
19 function SubType(name, age) {
20     SuperType.call(this, name);
21     this.age = age;
22 }
23 
24 inheritPrototype(SubType, SuperType);
25 
26 SubType.prototype.sayAge = function () {
27     var out1 = document.getElementById("out1");
28     var p = document.createElement("p");
29     p.innerHTML = this.age;
30     out1.appendChild(p);
31 };
32 
33 var out1 = new SuperType("Bob");
34 var out2 = new SubType("Cherry",21);
35 
36 console.log(out1);
37 console.log(out2);
38 out1.sayName();
39 out1.sayAge();
40 out2.sayName();
41 out2.sayAge();

效果如下,其中父類型構造函數沒有 age ,故輸出為 undefined

技術分享

END~~~≥ω≤

面向對象 ( OO ) 的程序設計——繼承