JavaScript 繼承(二)借用構造函數(shù)

在解決原型中包含引用類型值所帶來問題的過程中,開發(fā)人員開始使用一種叫做 借用構造函數(shù) 的技術(也叫做偽造對象或經典繼承)。

思想:在子類型構造函數(shù)的內部調用超類型構造函數(shù)。

函數(shù)只是在特定環(huán)境中執(zhí)行的代碼的對象,因此通過使用 apply() 和 call() 方法也可以在(將來)新創(chuàng)建的對象上執(zhí)行構造函數(shù)

function SuperType() {
    this.colors = ["red", "blue", "green"];
}
function SubType() {
    // 使用構造方法繼承了 SuperType
    SuperType.call(this);
}

var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors); // red,blue,green,black

var instance1 = new SubType();
alert(instance1.colors); // red,blue,green

SuperType.call(this); 調用了超類型的構造函數(shù)。通過使用 call() 方法(或 apply() 方法也可以),實際上是在(未來將要)新創(chuàng)建的 SubType 的實例的環(huán)境下調用了 SuperType 構造函數(shù)。這樣一來,就會在新 SubType 對象上執(zhí)行 SuperType 函數(shù)中定義的所有對象初始化代碼。結果,SubType 的每個實例就都會具有自己的 colors 屬性的副本了。

相對于原型鏈而言,借用構造函數(shù)有一個很大的優(yōu)勢,即可以在子類型構造函數(shù)中向超類構造函數(shù)傳遞參數(shù)。

其實沒學到這章時,一直不知道 call,apply 神奇在哪里,不就是一個改變 this 的方法嗎?要如何使用呢???現(xiàn)在才發(fā)現(xiàn),原來就是這么一個改變 this 的操作,能干出這么多花樣。

作為函數(shù)本身,我的構造方法不在是我自己的了,通過 call()、apply() 將一個函數(shù)從自身的維度解耦了,任何函數(shù)在創(chuàng)建時,都可以通過其他函數(shù)的構造方法來完善自身屬性。

實現(xiàn)了函數(shù)與函數(shù)之間的高度復用

function SuperType(name) {
    this.name = name;
}

function SubType() {
    // 繼承了 SuperType,同時還傳遞了參數(shù)
    SuperType.call(this, "Bert");

    // 實例屬性
    this.age = 24;
}

var instance = new SubType();

alert(instance.name); // Bert
alert(instance.age); // 24

SuperType 只接受一個參數(shù) name,該參數(shù)會直接賦給一個屬性。在 SubType 構造函數(shù)內部調用 SuperType 構造函時,實際上是為 SubType 的實例設置了 name 屬性。為了確保 SuperType 構造函數(shù)不會重寫子類型的屬性,可以在調用超類型構造函數(shù)后,在添加應該在子類型中定義的屬性。

借用構造的問題

如果僅僅是借用構造函數(shù),那么也將無法避免構造函數(shù)模式存在問題 ---- 方法都在構造函數(shù)中定義,因此函數(shù)復用就無從談起了。而且,在超類型的原型中定義的方法,對子類型而言是不可見的,結果所有類型都只能使用構造函數(shù)模式。

考慮到維護、使用上的不便因素,借用構造函數(shù)的技術很少單獨使用。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容