美文网首页
原型继承

原型继承

作者: 星球小霸王 | 来源:发表于2019-06-12 17:50 被阅读0次

    原型链的继承

    1.第一种继承方式(原型链继承)
    function Super(){
      this.company = '韩创';
      this.members = [1,2,3];
    }
    Super.prototype.getName = function(){
      console.log('super'+this.company)
    }
    
    function Sub(name,age){
      this.name = name;
      this.age = age;
    }
    Sub.prototype = new Super();
    //继承后要将构造函数也指向自己
    Sub.prototype.constructor = Sub;
    
    let sub = new Sub('Bryan',18);
    
    console.log(sub.hasOwnProperty('company'));// false
    console.log(sub.hasOwnProperty('name'));// true
    console.log(Sub.prototype.isPrototypeOf(sub));// true
    console.log(Super.prototype.isPrototypeOf(sub));// true
    
     /**第一次打印解析
     从打印结果来看
     1.父类对象 Super 里的 company 属性,虽然继承到了 派生对象 sub 身上,但是不属于它的自身属性
     2.父类对象的原型已经等于 派生对象 sub 的原型
    */
    
    let p1 = new Sub('p1',18);
    let p2 = new Sub('p2',20);
    p1.members.push(5);
    console.log(p2.members);//[1,2,3,5]
    /**
     * 第二次打印解析
     * 新建了两个对象 p1 和 p2 ,并且改变 p1 的属性 members
     * 从打印结果来看
     * 虽然改变的p1对象的members,但是p2的members也被改变了
     * 所以对于 原型链继承 当原型中存在引用类型值时,实例可以修改其值。
     * **/
    
    2.第二种继承方式(第二种继承方式)
    function Staff(){
      this.company = 'abc'
      this.members = [1,2,3]
    }
    Staff.prototype.getCompany = function(){
      console.log(this.company)
    }
    function Employee(name,age){
      Staff.call(this);
      this.name = name;
      this.age = age;
    }
    Employee.prototype.say = function(){
      console.log(this.name + this.age)
    }
    
    let user1 = new Employee('lily',19)
    let user2 = new Employee('lucy',20)
    user1.members.push(4)
    console.log(user2.members);//[1,2,3]
    console.log(user1.hasOwnProperty('company'));//true
    console.log(Staff.prototype.isPrototypeOf(user1));//false
    console.log(Staff.prototype.isPrototypeOf(user2));//false
    console.log(user1.getCompany());//user1.getCompany is not a function
    
    /**
     * 存在的问题
     * 只能继承父对象的实例属性和方法,
     * 不能继承父对象原型属性和方法
     * 无法实现函数复用,每个子对象都有父对象实例的副本,性能欠优
     * **/
    
    3.第三种继承方式(组合继承)
    function Animal(){
      this.home = 'abc'
      this.num = [1,2,3]
    }
    Animal.prototype.say = function(){
      console.log(this.home)
    }
    function Dog(name,age) {
        Animal.call(this);
        this.name = name;
        this.age = age;
    }
    Dog.prototype = new Animal();
    Dog.prototype.constructor = Dog;
    Dog.prototype.move = function(){
      console.log('dog move')
    }
    
    
    let dog1 = new Dog('xiaohei',1);
    let dog2 = new Dog('xiaobai',2);
    dog1.num.push(4)
    console.log(dog1.num);//[1,2,3,4]
    console.log(dog2.num)//[1,2,3]
    dog2.move()//dog move
    dog2.say()//'abc'
    
    console.log(dog1.hasOwnProperty('home'));//true
    console.log(dog1.hasOwnProperty('num'));//true
    console.log(Animal.prototype.isPrototypeOf(dog1));//true
    /****
        优点
            可以复用原型上定义的方法
            可以保证每个函数有自己的属性,可以解决原型中引用类型值被修改的问题
        缺点
            staff 会被调用 2 次:第 1 次是employee.prototype = new staff();
            第 2 次是调用 staff.call(this)。
     ***/
    

    相关文章

      网友评论

          本文标题:原型继承

          本文链接:https://www.haomeiwen.com/subject/cucrfctx.html