zoukankan      html  css  js  c++  java
  • js继承总结

    js的继承方式(共6种):

      定义一个父级函数:
    function Animal(name){ this.name = name; this.sleep = function(){ console.log(this.name+"在睡觉") } } Animal.prototype.eat = function(food){ console.log(this.name+"再吃"+food); }

      第一种:原型链继承(父类实例作为子类的原型)

    function Cat(name){
        this.name = name;
    }
    Cat.prototype.color = "白色";
    Cat.prototype = new Animal();
    var cat1 = new Cat("Tom");   //  实例1
    var cat2 = new Cat("Jim");    //  实例2
    var cat3 = new Cat("Sun");    //  实例3
    console.log(cat1.name);
    console.log(cat1.color);   //  undefined
    console.log(cat2.sleep());
    console.log(cat3.eat("fish"))
    
    特点:
         简单易实现
         父类实例的属性和方法子类都可以继承
    缺点:
         想要新增原型属性和方法必须放在new Animal()语句之后
         不能实现多继承(一个子类同时继承多个父类)
         来自原型对象的属性是所有实例共享的
         创建子类实例时,无法向父类构造函数传参      
        
    

      第二种:构造函数继承(通过使用call改变this指向,指向父类实例,相当于复制父类实例的属性给子类)

    function Cat(name){
        Animal.call(this);
        this.name = name;
    }
    var cat1 = new Cat("Tom");
    console.log(cat1.name);
    console.log(cat1.sleep());
    console.log(cat1.eat("fish"))   //  cat1.eat is not a function
    
    特点:
         可以实现多继承
         创建子类实例时可以向父类传参
    缺点:
         只能继承父类实例的属性和方法,不能继承原型的方法
         函数不可复用
         实例只是子类实例不是父类实例
        
    

      第三种:实例继承(为父类实例添加新属性,作为子类实例返回)

    function Cat(name){
        console.log(this)
        var instance = new Animal();
        instance.name = name;
        return instance;
    }
    var cat1 = new Cat("Tom");
    var cat2 = Cat("Jim");
    console.log(cat1.name)   // Tom
    console.log(cat2.name)   // Jim
    
    特点:
         不限制调用方式,new 构造函数  或者直接调用子类函数  得到的都是同样的结果
    缺点:
         不支持多继承
         实例是父类实例,不是子类的实例

    第四种:拷贝继承(获取父类实例,通过循环父类实例,把父类实例的属性和方法都赋给子类)

    function Cat(name){
        var animal = new Animal();
        for(var p in animal){
            Cat.prototype[p] = animal[p];
        }
        Cat.prototype.name = name;
    }
    var cat1 = new Cat("Jim");
    var cat2 = new Cat("Jim");
    console.log(cat1.name);
    console.log(cat2.eat("fish"));
    
    特点:
         可以实现多继承
    缺点:
         因为每次都要循环,造成内存消耗严重,效率低
         不可以枚举的属性方法就会获取不到
    

      第五种:组合继承(通过调用父类的构造函数,继承了父类的属性和方法,并保留了传参的优点,通过将父类实例作为子类的原型,实现了函数的复用)

    function Cat(name){
            Animal.call(this);
            this.name = name;
        }
        Cat.prototype = new Animal();
        Cat.prototype.constructor = Cat;
    //    console.log(Cat.prototype.constructor);
        var cat1 = new Cat("Tom");
        var cat2 = new Cat("Li");
        console.log(cat1.name);
        console.log(cat2.eat("apple"))
    特点:
         既可以继承实例的属性和方法,也可以继承构造函数的属性和方法
         子类实例可以给父类传参
         实例既是子类实例也是父类实例
         函数可复用
    缺点:
         调用了两次父类构造函数,生成了两份实例
         (1). 设置子类实例原型的时候  Cat.prototype = new Animal();
         (2). 创建子类实例的时候      var cat1 = new Cat("Tom");
    

      第六种:寄生组合继承

    function Cat(name){
            Animal.call(this);
            this.name = name;
        }
        (function(){
    //      创建一个没有实例方法的类
            var Cate = function(){
    
            }
    //      将父类原型当做这个类的原型
            Cate.prototype = Animal.prototype;
    //      把实例作为子类的原型
            Cat.prototype = new Cate();
        })()
        var cat1 = new Cat("Tom");
        var cat2 = new Cat("Jim");
        console.log(cat1);
        console.log(cat2.eat("apple"));
    特点:
         既可以继承实例的属性和方法,也可以继承构造函数的属性和方法
         子类实例可以给父类传参
         实例既是子类实例也是父类实例
         可以实现多继承
         函数可复用
         通过寄生的方式,去掉了父类的实例属性,调用两次父类构造函数时不会初始化两属性和方法
    

      

  • 相关阅读:
    第4課 部屋に机といずがあらます。
    (转)三层结构设计与ERP部署规划
    多线程的一个问题(同步事件和等待句柄)转
    C#操作xml小结(转)
    再论Assembly Registration Tool (Regasm.exe)
    再论Type Library Importer (Tlbimp.exe)
    Blittable and NonBlittable Types
    再论Importing a Type Library as an Assembly
    .Net Remoting(基本操作) Part.2 (转)
    Monitor类示例(转)
  • 原文地址:https://www.cnblogs.com/ly-qingqiu/p/10881870.html
Copyright © 2011-2022 走看看