說說構造函數中幾種繼承

1.call的借用繼承

	    function parent1() {
            this.name = "parent1"
        } 
        function child1() {
            parent1.call(this)
            this.type = 'child1'
        }
        parent1.prototype.say = function () {
            console.log('hi parent1')
        }
        var s1 = new child1();
        console.log(s1); //{name: "parent1", type: "child1"}
        console.log(s1.say()); //Uncaught TypeError: s1.say is not a function

上述代碼中,關於在parent1中的屬性,可以給子級繼承,但是在parent1原型鏈上的方法,無法給子級繼承。

2. 原型鏈繼承

	   function parent2() {
            this.name = 'parent2';
            this.arr = [1,2,3];
        }
        function child2 () {
            this.type = 'child2';
        }
        parent2.prototype.say = function () {
            console.log('hi parent2');
        }
        child2.prototype = new parent2();
        var a1 = new child2();
        var a2 = new child2();
        a1.say()  // hi parent2
        a2.say()  // hi parent2
        a1.arr.push(4);
        console.log(a1.arr, a2.arr);  //  [1, 2, 3, 4], [1, 2, 3, 4]

上述代碼中,child2構造函數的prototype屬性指向父級實例,子級實例中可以使用say方法,但是缺點是child2原型上的屬性值,所有實例皆可訪問。修改了一個實例,其他的都發生改變

3.組合繼承

        function parent3() {
            this.name = 'parent3';
            this.arr = [1,2,3];
        }
        function child3() {
            parent3.call(this);
            this.type = 'child3';
        }
        parent3.prototype.say = function () {
            console.log('hi parent3');
        }
        child3.prototype = new parent3();
        var a3 = new child3();
        var a4 = new child3();
        a3.say(); a4.say()  // hi parent3  
        a3.arr.push(4);
        console.log(a3, a4); //[1, 2, 3, 4], [1, 2, 3]

上述代碼中,使用call借用繼承屬性值,使用原型鏈繼承其中方法

4. 組合繼承的優化1

3中的代碼中,因爲屬性已經被call繼承,所以原型鏈中不需要再次繼承, 所以將

   child3.prototype = parent3.prototype    //  其他部分不變

5.組合繼承的優化2

在優化之前,先介紹一個創建對象的方法,Object.create可創建一個新對象,使用現有對象來爲新對象提供__proto__

	var p1 =  {"name": ''};
    var obj  = Object.create(p1);
    console.log(obj);

在這裏插入圖片描述

開始優化:

當對34中代碼打印時

        console.log(a3 instanceof parent3, a3 instanceof child3);
        console.log(a3.constructor);

在這裏插入圖片描述
它們的構造器都是parent3,父級構造,我們知道a3實例是由child3構造出的。所以要改變constructor的指向問題

 function parent5() {
            this.name = 'parent5';
            this.arr = [1,2,3];
        }
        function child5() {
            parent5.call(this);
            this.type = 'child5';
        }
        parent5.prototype.say = function () {
            console.log('hi parent5');
        }
        child5.prototype = Object.create(parent5.prototype); //原型指向一個空對象實例,空對象的__proto__指向parent5.prototype
        child5.prototype.constructor = child5;
        var s3 = new child5();
        var s4 = new child5();
        s3.say(); s4.say()  // hi parent5  
        s3.arr.push(4);
        console.log(s3, s4);  //[1, 2, 3, 4], [1, 2, 3]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章