zoukankan      html  css  js  c++  java
  • js中的几种继承方法

    JS作为面向对象的弱类型语言,继承也是其非常强大的特性之一。

    继承:子承父业;一个原本没有某些方法或属性的对象,统一写方法,拿到了另外一个对象的属性和方法

    下面是js中的几种继承方式

    1.改变this指向继承(构造函数继承):继承构造函数中的属性和方法

     function Parent(n){
            this.name = n;
            this.skill = function(){
                console.log(this.name + "是篮球运动员");     //樱木花道是篮球运动员
                                                           //泽北荣治是篮球运动员
            }
        }
        Parent.prototype.init = function(){
            console.log(123)                               //123
        }
    
        // function P2(){
        //     this.a = 10;
        // }
        // function P3(){
        //     this.b = 20;
        // }
        // function P4(){
        //     this.c = 30;
        // }
        
        function Child(n){
            // Parent.bind(this,n)();
            // P2.bind(this)()
            // P3.bind(this)()
            // P4.bind(this)()
    
            // Parent.call(this,n);
    
            Parent.apply(this,arguments);
        }
    
        var p = new Parent("樱木花道");
        console.log(p)
        p.skill();       //
        p.init()
    
        var c = new Child("泽北荣治");
        console.log(c)
        c.skill();           //   
        // console.log(c.a)
        // console.log(c.b)
        // console.log(c.c)
        // c.init()
    

    优点:简单方便易操作,可以多继承

    缺点:只能继承构造函数,不能继承原型

    2.原型对象继承:继承原型

    function Parent(n){
            this.name = n;
        }
        Parent.prototype.skill = function(){
            console.log(this.name + "是鉴定师");       //大老王是鉴定师
                                                     //小老王是鉴定师
        }
    
        function Child(n){
            this.name = n;
        }
    
        // 注意:对象的深浅拷贝
        for(var i in Parent.prototype){
            Child.prototype[i] = Parent.prototype[i];
        }
    
    
        var p = new Parent("大老王");
        console.log(p)                            //Parent {name: "大老王"}
        p.skill();
    
        var c = new Child("小老王");
        console.log(c)                            //Child {name: "小老王"}
        c.skill();
    

    优点:简单,方便,可以继承原型身上的方式和属性
    缺单:只能继承原型,不方便传参

    3.原型链继承:通过给Child设置原型为Parent的实例的方式,给Child添加了一层原型链的方式

     function Parent(n){
            this.name = n;
        }
        Parent.prototype.skill = function(){
            console.log(this.name + "是鉴定师");           //大老王是鉴定师
        }
    
        function Child(){}
        Child.prototype = new Parent("小老王");
    
        Child.prototype.skill = function(){
            console.log(this.name+"是运动员")             //小老王是运动员
        } 
    
        var p = new Parent("大老王");
        console.log(p)                                 //Parent {name: "大老王"}
        p.skill();
        // p是实例(对象),有__proto__属性,指向Parent.prototype
    
        var c = new Child();
        console.log(c);                              //Child {}
        c.skill();
        // c是实例(对象),有__proto__属性,指向Child.prototype,是Parent的实例(对象),有__proto__属性,指向Parent.prototype
    

    优点:既能继承原型,又能继承构造函数
    缺点:复杂,不方便传参

    4.混合继承:构造函数继承+原型对象继承

     function Parent(n){
            this.name = n;
        }
        Parent.prototype.skill = function(){
            console.log(this.name + "是鉴定师");              //大老王是鉴定师
        }
    
        function P2(){
            this.a = 10;
        }
        P2.prototype.init = function(){
            console.log("hello")                        //hello
        }
    
        function Child(n){
            Parent.call(this,n)
            P2.call(this)
        }
        for(var i in Parent.prototype){
            Child.prototype[i] = Parent.prototype[i]
        }
        for(var i in P2.prototype){
            Child.prototype[i] = P2.prototype[i]
        }
    
        Child.prototype.skill = function(){
            console.log(123)                            //123
        }
       
    
        var p = new Parent("大老王");
        console.log(p)                           //Parent {name: "大老王"}
        p.skill();
    
        var c = new Child("小老王");
        console.log(c)                          //Child {name: "小老王", a: 10}
        c.skill();
        c.init();
    

    优点:既能继承构造函数又能继承原型,方便传参,多继承

    缺点:复杂

    常用的继承方式之一

    5.ES6的class继承

    class Parent{
            constructor(n) {
                this.name = n
            }
            skill(){
                console.log(this.name + "是鉴定师")         //大老王是鉴定师
                                                          //小老王是鉴定师
            }
        }
    
        class Child extends Parent{
            constructor(n){
                super(n)
            }
        }
    
        var p = new Parent("大老王");
        console.log(p)                              //Parent {name: "大老王"}
        p.skill();
    
        var c = new Child("小老王");                //Child {name: "小老王"}
        console.log(c)
        c.skill();
    

    优点:简单方便易操作,语法层面的继承,属性和方法都能继承,参数很好处理

    缺点:兼容性

    忽略兼容,常用的继承方式之一

  • 相关阅读:
    WPF中DataGrid控件的数据绑定与显示数组
    WPF中添加个简单的显示当前系统时间的示例
    WPF中往ComboBox里添加选项并指定默认选项
    WPF中Button的四种状态
    Web安全新变化 智能手机是下一个进攻点 狼人:
    卡巴斯基重拳组合 高效应对高考网站挂马 狼人:
    DNS规模故障追踪:由24岁站长引发的蝴蝶效应 狼人:
    追踪多省网络故障:域名解析瘫痪后的连锁反应 狼人:
    化解SaaS安全问题的三大措施 狼人:
    报道称黑客利用微软IIS安全漏洞 入侵大学服务器 狼人:
  • 原文地址:https://www.cnblogs.com/mhcll/p/11563142.html
Copyright © 2011-2022 走看看