zoukankan      html  css  js  c++  java
  • js对象继承

    现有一个父类:

    function People(name){
      //属性
      this.name  = name
      //实例方法
      this.sleep=function(){
        console.log(this.name + '正在睡觉')
      }
    }
    //原型方法
    People.prototype.eat = function(food){
      console.log(this.name + '正在吃:' + food);
    }

    我们现在要构造一个子类woman,woman需要拥有people的属性和方法

    1.原型链继承

    function People(name){
      //属性
      this.name  = name || Annie
      //实例方法
      this.sleep=function(){
        console.log(this.name + '正在睡觉')
      }
    }
    //原型方法
    People.prototype.eat = function(food){
      console.log(this.name + '正在吃:' + food);
    }
    
    function Woman(){ 
    }
    Woman.prototype= new People('haha');
    let womanObj = new Woman();
    womanObj.sleep()  //haha正在睡觉
    womanObj.eat('xiangjiao')  //haha正在吃:xiangjiao

    缺点:womanObj中的name是唯一的,因为Woman.prototype= new People('haha'),Woman继承时以及传入了name,因此按需构造多个实例。

    2.构造继承

    function Woman(name){
     //继承了People
      People.call(this,name);
    }
    let womanObj = new Woman('haha');
    womanObj.sleep() //haha正在睡觉
    womanObj.eat('xiangjiao')  // Uncaught TypeError: womanObj.eat is not a function

    优点:解决了无法构造多个实例的缺点,同时父类可以有多个,只需要在Women中使用call就可以了,例如增加多一个父类People2.call();

    缺点:但同时也带来了问题:无法继承父类中原型链上的方法,例如本例中womanObj中调用eat导致报错。

    3.实例继承

    function Woman(name){
      let instance = new People();
      instance.name = name
      return instance;
    }
    let womanObj = new Woman('haha');
    console.log(womanObj instanceof People) //true console.log(womanObj instanceof Woman) //false womanObj.sleep() //haha正在睡觉 womanObj.eat('xiangjiao') //haha正在吃:xiangjiao

    解决了原型链的继承的问题,但实际上womanObj是people的实例,而不是woman的实例了,有点借壳上市的感觉。

    4.组合继承

    function Woman(name){
      People.call(this,name)
    }
    Woman.prototype = People.prototype;
    let womanObj = new Woman('haha');
    Woman.prototype.constructor = Woman; //为了让constructor从people指向women
    console.log(womanObj instanceof Woman) //true console.log(womanObj instanceof People) //true womanObj.sleep() //haha正在睡觉 womanObj.eat('xiangjiao') //haha正在吃:xiangjiao

    效果其实和实例继承差不多。缺点是调用了两次父类,同时在Women.prototype上写东西会污染People.prototype

    例如:

    Woman.prototype.food = 'pingguo'
    console.log(People.prototype.food) // pingguo

     想不污染people.prototype其实改动一行就可以了:

    Woman.prototype = Object.create(People.prototype)

    这其实和下面讲到的寄生组合继承思想是相类似的。

    5.寄生式组合继承

    function Woman(name){
      //继承父类属性
      People.call(this,name)
    }
    //继承父类方法
    (function(){
      // 创建空类
      let Super = function(){};
      Super.prototype = People.prototype;
      //父类的实例作为子类的原型
      Woman.prototype = new Super();
    })();
    //修复构造函数指向问题
    Woman.prototype.constructor = Woman;
    Woman.prototype.food = 'pingguo'
    console.log(People.prototype.food)  //undefined
    let womanObj = new Woman('haha');
    console.log(womanObj instanceof Woman)  //true
    console.log(womanObj instanceof People)   //true
    womanObj.sleep()  //haha正在睡觉
    womanObj.eat('xiangjiao')   //haha正在吃:xiangjiao

    所谓寄生,就是把Woman.prototype寄生在了super对象上,这样Women.prototype上的属性和方法就不会污染到People.prototype

    6.ES6继承

    class People{
      constructor(name='wang'){
        this.name = name;
      }
      eat(){
        console.log(`${this.name} eat food`)
      }
    }
    
    class Woman extends People{ 
    } 
    let womanObj=new Woman('xiaoxiami'); 
    womanObj.eat() //xiaoxiami eat food

    优点:代码简单,没有原型链等概念,继承效果好。

  • 相关阅读:
    MVC @Url.Action 小示例
    Eclipse快捷键
    MVC视频下载/文件上传
    MySQL数据库备份/导出
    C#文件下载
    C#正则表达式匹配字符串中的数字
    常用的LINQ to SQL 用法
    C# 实现抓取网页内容(一)
    C# 繁体字和简体字之间的相互转换
    我到底会什么??
  • 原文地址:https://www.cnblogs.com/AwenJS/p/12698617.html
Copyright © 2011-2022 走看看