简述继承方法

ES5继承

先定义一个父类

	// 1.定义父类 (包含实例属性和方法)
	function Animal(name) {
	    this.name = name || 'Animal';
	    this.sleep = function () {
	        console.log(this.name + "正在睡觉!")
	    }
	}
	// 原型方法
	Animal.prototype.eat = function (food) {
	    console.log(this.name + "正在吃" + food);
	}

1. 原型链继承

实现:将父类的实例作为子类的原型对象

	// 2.定义子类
    function Cat() { }
    Cat.prototype = new Animal(); //!将父类的实例作为子类的原型对象
    Cat.prototype.name = "cat";

    var cat = new Cat();
    console.log(cat.name); //cat
    cat.eat("fish"); //cat正在吃fish
    cat.sleep(); //cat正在睡觉!
    console.log(cat instanceof Animal); //true
    console.log(cat instanceof Cat); //true

特点:

  1. 非常纯粹的继承关系,实例 cat 既是父类的实例,也是子类的实例
  2. 子类能访问到父类的所有属性和方法(包括原型属性和方法)

缺点:

  1. 无法实现多继承
  2. 来自原型对象的引用属性是所有实例共享的
  3. 创建子类实例时,无法向父类构造函数传参

2. 构造继承

实现:让父类的 this 指向子类,复制父类的实例属性和方法给子类

	// 2.定义子类
    function Cat(name) {
        Animal.call(this); //!让父类的this指向子类,复制父类的【实例属性和方法】给子类
        this.name = name || "Tom"
    }
    //Test Code
    var cat = new Cat("cat");
    console.log(cat.name);  //cat
    cat.sleep();  //cat正在睡觉!
    // cat.eat("fish"); //报错:cat.eat is not a function
    console.log(cat instanceof Animal);  //false
    console.log(cat instanceof Cat); //true

特点:

  1. 创建子类实例时,可以向父类传递参数
  2. 可实现多继承(call 多个父类对象)

缺点:

  1. 实例 cat 是子类的实例,不是父类的实例
  2. 只能继承父类的实例属性方法,不能继承其原型属性方法
    (解决原型链继承中,子类实例共享父类引用属性的问题)
  3. 每个子类都有父类实例属性和方法的副本,影响性能

3. 实例继承

实现:为父类实例添加新属性和方法,作为子类实例返回

	// 2.定义子类
    function Cat(name) {
        var instance = new Animal();
        instance.name = name || "Tom"; //!为父类实例添加新属性、方法,作为子类实例返回
        return instance;
    }

    var cat = new Cat();
    console.log(cat.name); //Tom
    cat.sleep();  //Tom正在睡觉!
    cat.eat("fish"); //Tom正在吃fish
    console.log(cat instanceof Animal); //true
    console.log(cat instanceof Cat); //false

特点:不限制调用方法,不管是 new 子类()还是子类(),具有相同的效果

缺点:

  1. 实例 cat 是父类的实例,但不是子类的实例
  2. 不支持多继承

ES6继承

	// 定义父类 
    class Person {
      constructor(skin,language) {
        this.skin = skin
        this.language = language
      }
      say() {
        console.log("I'm a Person")
      }
     }
     // 子类继承 
     class American extends Person {
       /*有无注释效果都一样*/
       // constructor(skin,language) {
       //     super(skin,language)
       // }
       aboutMe() {
         console.log(this.skin+" "+this.language)
       }
      }

      var m = new American("张三","中文")
      m.say() //I'm a Person
      m.aboutMe() //张三 中文

子类调用 super 函数是为了在子类中获取父类的 this(即执行父类.prototype.constructor.call(this)),使用父类的属性和方法。

  • 子类中没有 constructor 时,会默认添加一个并在 constructor 中执行 super 函数,即调用父类的构造函数
  • 子类中有 constructor 时,必须在 constructor 中执行 super 函数,否则 new 实例时会报错(子类没有自己的 this 对象)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值