1. 程式人生 > 實用技巧 >js函式的物件的繼承

js函式的物件的繼承

1.原型鏈繼承:將父親的例項賦給子類的原型。

缺點:如果有一個子類例項改變所繼承的內容,則當下一個子類例項繼承是會是上一個子類改變之後的內容,而不是原有父親的內容。

(解決:物件冒充繼承方法)

function Father(name, age) {
            this.name = 'li';
            this.age = 3;
            this.arr = [1, 2, 3];
        }
        function Son(sex) {
            this.sex = sex;
        }
        Son.prototype 
= new Father; //將父類的例項賦值給子類的原型 var son1 = new Son('男'); //new一個子類的例項son1 var son2 = new Son('女'); //new一個子類的例項son2 console.log(son1.arr); //列印son1繼承的屬性arr [1, 2, 3] son1.arr.push(4); //通過son1改變arr的值 此時改變的是子類的原型鏈 console.log(son2.arr); //再用son2列印arr值 [1, 2, 3, 4]

2.物件冒充繼承: 通過call或其他方法改變父類中的this指向,讓父類的this指向那子類,這樣子類例項物件就可以使用父類中的屬性和方法。

優點: 解決了原型鏈繼承引用型別共用的問題 。

缺點:不能呼叫父類原型鏈中的方法函式。(解決:組合模式方法)

function Father(name, age) {
            this.name = 'li';
            this.age = 3;
            this.arr = [1, 2, 3];
            this.sayHi = function() {
                return 'Hi' + this.name;
            }
        }
        Father.prototype.showName 
= function() { return this.name; } function Son(sex) { Father.call(this); //通過call改變Father的this指向Son,這樣就可以使Son中擁有Father的屬性 this.sex = sex; } var son1 = new Son('男'); console.log(son1); //Son{nme: "li", age: 3, arr: Array(3), sex: "男", sayHi: ƒ} console.log(son1.name); //li console.log(son1.sayHi()); //可以呼叫父類本身具有的方法 Hili // console.log(son1.showName()); //報錯 son1.showName is not a function //缺點:不能呼叫父類原型鏈中的方法函式 //---------------------------------------------------------- //解決了原型鏈中一個子類物件改變父類屬性會影響其他子類的問題 son1.arr.push(4); console.log(son1.arr); //[1, 2, 3, 4] var son2 = new Son(); console.log(son2.arr); //[1, 2, 3]

3.組合繼承:利用物件冒充繼承父類本身的屬性和方法,利用原型鏈繼承父類原型上的方法

優點:解決了不能呼叫父類原型鏈中的方法函式;

缺點: 1.相同的屬性,在原型鏈上出現了兩次(讀取沒有問題,因為子例項上面的屏閉了 原型上面的屬性)

2.父類的建構函式呼叫了兩次

解決:寄生組合繼承

function Father(name, age) {
            this.name = 'li';
            this.age = 3;
            this.arr = [1, 2, 3];
            this.sayHi = function() {
                return 'Hi' + this.name;
            }
        }
        Father.prototype.showName = function() {
            return this.name;
        }

        function Son(sex) {
            Father.call(this); //通過call改變Father的this指向Son,這樣就可以使Son中擁有Father的屬性 呼叫一次
            this.sex = sex;
        }
        Son.prototype = new Father(); //通過原型鏈繼承父類原型中的方法 呼叫兩次
        var son1 = new Son('男');
        console.log(son1); //Son{name: "li", age: 3, arr: Array(3), sex: "男", sayHi: ƒ}
        console.log(son1.showName()); //li
        console.log(son1.sayHi()); //Hili

可以看到age,arr,name,sayHi在原型鏈中出現了兩次。

4.寄生組合繼承:(完美)

function Father(name, age) {
            this.name = 'li';
            this.age = 3;
            this.arr = [1, 2, 3];
            this.sayHi = function() {
                return 'Hi' + this.name;
            }
        }
        Father.prototype.showName = function() {
                return this.name;
            }
            //  Son.prototype = new Father;//不能直接繼承父類
            // 父的例項,不能直接賦給子的原型,利用一箇中間函式中轉一下
        function Son(sex) {
            Father.call(this); // 利用物件冒充繼承繼承屬性Father的屬性
            this.sex = sex;
        }

        // var F = function() {};
        // F.prototype = Father.prototype;
        // Son.prototype = new F();
        // Son.prototype.constructor = Son;
        inherits(Son, Father); // 調這個封裝函式,相當於上面四句話
        // 子的原型上的方法,必須在呼叫inherits以後,再新增
        var son1 = new Son('男');
        console.log(son1.showName()); //li
        function inherits(Child, Parent) {
            var F = function() {};
            F.prototype = Parent.prototype;
            Child.prototype = new F();
            Child.prototype.constructor = Child;
        }