zoukankan      html  css  js  c++  java
  • 关于JS的继承总结

    最近都在巩固JS的基础知识,今天组要看的是有关继承方面的,每次看都会加深自己的理解呢

    1.借助构造函数实现继承

    原理:在子类中改变父类this的指向

     function Parent1() {
            this.name = 'parent1';
        }
        function Child1() {
            Parent1.call(this); //也可以使用 apply,改变函数运行的上下文;将父级的构造函数的this指向子类的实例
            this.type = 'child1';
        }
        console.log(new Child1());

    在控制台打印的信息可以看出,Child1的实例继承了Parent1的name属性

    缺点:不能继承父类原型对象上的方法或属性

    在原有代码的基础上做如下修改:

     function Parent1() {
            this.name = 'parent1';
        }
    
        Parent1.prototype.say = function () {
            console.log('hi');
        };
        Parent1.prototype.color='red';
    
        function Child1() {
            Parent1.call(this); 
            this.type = 'child1';
        }  
          var s=new Child1();

    在控制台进行查看,可以看到s并没有继承color属性和say()方法

    2.借助原型链实现继承

    function Parent2() {
            this.name = 'parent2';
        }
    
        function Child2() {
            this.type = 'child1';
        }  
    /**
    *原型链继承原理:s1是Child2的实例对象,它的__ptoro__属性指向Child2的原型对象,
    *即Child2.prototype;代码中Child2.prototype=new Parent2(),等于Parent2的实例对
    *象,因此可以继承Parent2
    */
    Child2.prototype=new Parent2();    //重点
    var s1 = new Child2();

    缺点:原型链上的对象共享;如果父类Parent2中包含引用类型的属性,不同子类上的该属性是共享的,改变任意一个的值都会影响其他。

    function Parent2() {
            this.name = 'parent2';
            this.play = [1, 2, 3];
        }
    
        function Child2() {
            this.type = 'child2';
        }
    
        Child2.prototype = new Parent2();   //重点
    
        var s1 = new Child2();
        var s2 = new Child2();
        console.log(s1.play, s2.play);
        s1.play.push(4);
        console.log(s1.play, s2.play);

    虽然只改变了s1的play属性,但s2的也被改变了

    3.组合继承方式;构造函数+原型链相结合

    function Parent3() {
            this.name = 'parent3';
            this.play = [1, 2, 3];
        }
    
        function Child3() {
            Parent3.call(this);
            this.type = 'child3';
        }
    
        Child3.prototype = new Parent3();   
    
        var s3 = new Child3();
        var s4 = new Child3();
        s3.play.push(4);
        console.log(s3.play, s4.play);
    //注意:s3.constructor是Parent3

    组合方式虽然解决了共享的问题,即s3的play值得改变不会影响s4的play值;但是这种方式会使父级的构造函数执行两次,因此可以进行优化。

    3-1.组合继承方式的优化1

    function Parent4() {
            this.name = 'parent4';
            this.play = [1, 2, 3];
        }
    
        function Child4() {
            Parent4.call(this);
            this.type = 'child4';
        }
        Child4.prototype = Parent4.prototype;   
    
        var s5 = new Child4();
        var s6 = new Child4();
        s5.play.push(4);
        console.log(s5, s6);

    不足:无法识别实例是由子类直接实例化还是由父类直接实例化的;s5的constructor是Parent4;因为Child4.prototype = Parent4.prototype;

     3.2 组合继承的完美写法

    function Parent5() {
            this.name = 'parent5';
            this.play = [1, 2, 3];
        }
    
        function Child5() {
            Parent5.call(this);
            this.type = 'child5';
        }
    //Object.create创建一个中间对象,原型对象是父类的原型对象
        Child5.prototype = Object.create(Parent5.prototype);   
        Child5.prototype.constructor = Child5
    
        var s7 = new Child5();
        var s8 = new Child5();
        console.log(s7, s8);

  • 相关阅读:
    时钟展频技术能有效降低EMI,深入讲解展频发生器!
    24:购物单
    22:按照字典输出字符串
    21:句子逆序
    20:字符反转
    19:ReverseNumber数字颠倒
    DNS原理及其解析过程
    18:字符个数统计
    17:不重复整数提取NoRepeatNum
    \s+ split替换
  • 原文地址:https://www.cnblogs.com/jingmi-coding/p/8998583.html
Copyright © 2011-2022 走看看