iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 21
0
自我挑戰組

邁向 JavaScript 核心之路 系列 第 21

[Day 21] JavaScript 物件繼承- 傳遞參數到父層類別

  • 分享至 

  • xImage
  •  

傳遞參數到父層類別

大給後,對於昨天的文章提到的繼承原型方法,不知道大家是否理解了呢?

今天我們要針對那個方法再做一些延伸與調整,我們利用 call 的方式並沒有辦法傳遞參數到父層類別,因為使用 call 沒有帶入傳入的參數,所以我們可以改用 apply 將 arguments 傳入父層類別中。

就讓我們看看下方的程式碼吧!


    function A(abc) {
        this.abc = abc || 12;
        console.log("A Class"); // 繼承時會執行兩次
    }
    
    A.prototype.show = function() {
        console.log(this.abc);
    };
    
    function B() {
        A.apply(this, arguments);
    }
    
    B.prototype = new A();
    var objB = new B(11);
    
    B.prototype.square = function() {
        console.log( this.abc * this.abc );
    };
    
    objB.square(); 121
    

另外我準備了這段程式碼的原型鏈圖,讓讀者們可以更好理解其中的相對關係。

https://ithelp.ithome.com.tw/upload/images/20191006/20109495uytnj1pEXr.jpg

這樣我們就做到了傳遞參數到父層類別,但有些人會疑問,為什麼我特別寫了 繼承時會執行兩次
沒錯,上述的做法有一個缺點,就是在會讓父類別的建構函式重複執行了兩次,下一段,我們就要來解決這個問題。

暫時類別繼承方法

使用暫時類別的繼承方法,不會讓父類別的建構函式執行兩次。利用暫時類別的 prototype 設定父類別的 prototype,子類別的 prototype 再設定暫時類別產生出來的物件。

子類別 super 方法設定父類別的 prototype,最後重新設定子類別 prototype.constructor 到子類別,否則會造成子類別的 constructor 會變成是父類別的 constructor。

是不是有點繞口?沒關係,現在就讓我們看程式碼吧!

    // 在 Function 的 原型上擴充一個叫 inherits 的方法
    
    Function.prototype.inherits = function(superCtor) {
        function F() {
        };
        // 利用暫時類別的 prototype 設定父類別的 prototype
        F.prototype = superCtor.prototype;
        // 子類別的 prototype 設定成暫時類別產生出來的物件
        this.prototype = new F();
        // 子類別 super 方法設定父類別的 prototype
        this.super = superCtor.prototype;
        // 設定子類別 的 prototype.constructor 到子類別
        this.prototype.constructor = this;
    };
    
    function A(abc) {
        this.abc = abc || 12;
        console.log("A Class");
    };
    
    A.prototype.show = function() {
        console.log(this.abc);
    };
    
    function B() {
        A.apply(this, arguments);
    }
    
    B.inherits(A);
    var objB = new B(11);
    
    B.prototype.square = function() {
        console.log( this.abc * this.abc );
    };
    
    objB.square(); // 121
    

這樣我們就避免了父類別的建構函式重複執行,如果還是不太明白的讀者們,可以看看下方的原型鏈圖哦!

https://ithelp.ithome.com.tw/upload/images/20191006/20109495uFEw79hRmC.jpg

若是讀這段感覺到很吃力的讀者別太緊張,因為 ES6 的語法糖 Class 已經幫我們大大的簡化這部分的程式碼囉,所以可以先懂其中的概念就好。


下週就是國慶連假了,窩豪興奮 RRRR

參考資料:

Tommy - 深入 JavaScript 核心課程


上一篇
[Day 20] JavaScript 物件繼承- 繼承原型方法
下一篇
[Day 22] JavaScript 物件繼承- Object.creat 繼承方法
系列文
邁向 JavaScript 核心之路 30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言