Js繼承的方式

//-- 原型鏈繼承
function Parent(name) {
    this.name = name;
    this.sum = function () {
        console.log("this.name=", this.name);
    }
}
Parent.prototype.age = 10;

function Per() {
    this.name = "Per";
}
Per.prototype = new Parent();
var per1 = new Per();
console.log("per1.age=", per1.name); //-- per1.age= Per
per1.sum(); //-- this.name= Per
console.log("per1.age", per1.age);//-- per1.age 10
//-- 判斷Parent是否在per1的原型鏈上
console.log(per1 instanceof Parent); // -- true

//-- 重點:讓新實例的原型等於父類的實例
//-- 特點:新實例具有本身構造函數的屬性,繼承父類構造函數的屬性,繼承父類原型屬性。
//-- 缺點:  
//-- 1.所有新實例都共享父類的原型屬性(任意實例修改了原型屬性,所有的實例的原型屬性都將被修改)
//-- 2.不能給父類構造傳參

//------------------------------------------------------------------------------------------------------------------------------
//-- 借用構造函數繼承
function Con()
{
    Parent.call(this, "ConName");
    this.age1 = 122;
}
var con = new Con();
console.log("con", con); //-- con Con { name: 'ConName', sum: [Function], age: 122 }
console.log("con.age", con.age);
//-- 重點:用call()/apply() 在子類構造函數中調用父類造函數,將父類構造函數的屬性複製到子類中。
//-- 特點:
//-- 1.只繼承了父類的構造函數中的屬性,並沒有繼承父類的原型屬性
//-- 2.可以繼承多個構造函數的屬性,即可以多次調用call(),將其他父類構造函數的屬性複製到子類中。
//-- 3.可以給父類構造函數傳參
//-- 缺點: 每個新實例都有父類構造函數的副本
//------------------------------------------------------------------------------------------------------------------------------
// -- 將原型鏈繼承和調用構造函數繼承進行組合使用(組合繼承:常用)
function subType() {
    Parent.call(this, "subType");
}
subType.prototype = new Parent();
var subTypeObj = new subType();
console.log(subTypeObj); //-- Parent { name: 'subType', sum: [Function] }
console.log(subTypeObj.age); //-- 10
//-- 缺點: 調用兩次構造,第二次子類Call調用的構造函數覆蓋第一次調用的構造函數。
//------------------------------------------------------------------------------------------------------------------------------
// -- 原型式繼承
function content(obj){
    function F(){
    }
    F.prototype = obj;
    console.log("F.prototype == ", F.prototype); //-- F.prototype ==  Parent { name: undefined, sum: [Function] }
    return new F();
}
var sub = new Parent();
var sub1 = content(sub);
console.log("sub == ", sub);    //-- sub ==  Parent { name: undefined, sum: [Function] }
console.log("sub1 == ", sub1);    //-- sub1 ==  Parent {}
console.log("sub1.age == ", sub1.age); //-- sub1.age ==  10
console.log("sub1.sum == ", sub1.sum); //--   sub1.sum ==  function () {
                                       //--         console.log("this.name=", this.name);
                                       //--     }

//-- 重點:用一個函數包含一個函數,最後返回這個函數對象。這個對象就變成了個可以隨意增添屬性的實例或對象。object.create()就是這個原理。
//-- 函數的原型等同於一個實例
//-- F構造函數裏沒有成員,F的原型對象繼承了Parent的實例
//-- 所有實例都會繼承原型上的屬性
//------------------------------------------------------------------------------------------------------------------------------
// -- 寄生式繼承(就是在原生集成上套了一層套子)
function content(obj){
    function F(){

    }
    F.prototype = obj;
    return new F();
}
var sub = new Parent();
//-- 以上是原生繼承的一部分,下面給原生繼承的 var sub1 = content(sub); 套套子。
function subObj(obj){
    var sub1 = content(obj);
    sub1.xxx = function(){
        console.log("XXXX  哈哈哈");
    }
    return sub1;
}

console.log(subObj(sub));//-- Parent { xxx: [Function] }
console.log(subObj(sub).age); //-- 10
console.log(subObj(sub).sum); // -- [Function]
//------------------------------------------------------------------------------------------------------------------------------
// -- 寄生組合式繼承(常用)
// -- 就是寄生和構造的結合
// --寄生,先複製基類的prototype
function content(obj){
    function F(){}
    F.prototype = obj;
    return new F();
}
let con1 = content(Parent.prototype);

// --準備子類, 在子類中在複製構造函數的內容
function Sub(){
    Parent.call(this, "寄生構造的組合繼承");
}
//-- 繼承con的實例
Sub.prototype = con1;
//-- (一定要修復實例)修補構造函數
con1.constructor = Sub;
var sub = new Sub();
console.log(sub.age);  //-- 10
console.log("------------------------");
console.log(sub); //-- Sub { name: '寄生構造的組合繼承', sum: [Function] }          實例屬性
console.log(Parent);  //-- [Function: Parent]                                     函數對象屬性
console.log(Parent.prototype);  //-- Parent { age: 10 }                           函數對象的原型屬性
Parent.AAA = 656;
console.log("------------------------");
console.log(sub); //-- Sub { name: '寄生構造的組合繼承', sum: [Function] }
console.log(Parent);  //-- { [Function: Parent] AAA: 656 }
console.log(Parent.prototype);  //-- Parent { age: 10 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章