当前位置:首页 > js javascript面向对象继承的几种方法

js javascript面向对象继承的几种方法

发布于 2018-04-17 阅读 631 次 面向对象 Javascript

比如现在有一个 Animal类

  1. function Animal () {
  2. this.name = "动物";
  3. this.eat = function(){
  4. console.log('动物可以吃');
  5. }
  6. }
  7. Animal.prototype.say = function(){
  8. console.log(this.name +' 发出声音')
  9. }

有一个猫类

  1. function Cat (){
  2. this.name = "猫"
  3. }

现在要实现猫类继承动物类。

原型继承方式

将父类的一个实例赋值给子类的原型

  1. Cat.prototype = new Animal();
  2. Cat.prototype.constructor = Cat;

Cat.prototype = new Animal();这行会改变Cat.prototype 的constructor指向,由于实例的constructor也是调用prototype的constructor,而由Cat类创建的实例constructor本应该是Cat所以需要重新将Cat.prototype.constructor指向Cat
缺点:无法像父类构造函数传参,无法实现多重继承。

构造继承

在子类的构造函数中调用父类构造函数

  1. function Cat(){
  2. Animal.apply(this, arguments);
  3. this.name="猫";
  4. }

缺点:这种继承方式只能继承实例属性和方法不能继承父类原型上的方法

直接继承prototype

我们可以让子类的prototype直接继承父类的prototype

  1. Cat.prototype = Animal.prototype;

缺点:这种方法有问题,Cat.prototype 和 Animal.protype会指向同一个空间,修改一个都会影响另一个。

通过空函数做媒介,实现组合继承

  1. F = function(){}
  2. F.prototype = Animal.prototype;
  3. function Cat(){
  4. this.name = "猫";
  5. Animal.apply(this,arguments); //得到父类的实例属性和方法
  6. }
  7. Cat.prototype.constructor = Cat;
  8. Cat.prototype = new F(); //得到父类的原型属性和方法
  9. //可以封装成一个函数,方便使用
  10. function extend(Child, Parent){
  11. var F = function(){};
  12. F.prototype = Parent.prototype;
  13. Child.prototype = new F();
  14. }

拷贝继承

  1. function Cat(name){
  2. var animal = new Animal();
  3. for(var p in animal){
  4. Cat.prototype[p] = animal[p];
  5. }
  6. Cat.prototype.name = name || 'Tom';
  7. }

这里可能会涉及到一个深度拷贝的问题,拷贝的时候需要判断类型,如果是基本类型就直接赋值,如果不是需要进行深度拷贝。

相关知识:

对象的浅复制和深度克隆

共 2 条评论