说说构造函数中几种继承

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]
发布了8 篇原创文章 · 获赞 1 · 访问量 285

猜你喜欢

转载自blog.csdn.net/weixin_42442445/article/details/95459527