JS 的继承

139 阅读2分钟

原型继承

  • 比如我有dog对象及其属性和方法,并希望将Goldenretrieverdog作为基于dog稍加修改的变体。
let dog = {
  leg: 4
};
let Goldenretrieverdog ={
   hair:"Gold"
}
Goldenretrieverdog.__proto__ = dog; 

console.log(Goldenretrieverdog.leg)  // 打印出4
  • 注意:

    1. JavaScript中,对象有一个特殊的隐藏属性Prototype,它要么为null,要么就是对另一个对象的引用。该对象被称为`“原型”``
    2. 因为Prototype是隐藏的,我们可以用__proto__来设置他
    3. __proto__Prototype是不同的,我们默认只不过XXX._proto_好等于某个函数的prototype
  • 通过上述代码我们可以看到,在对象Goldenretrieverdog他是不含有leg,但是我们却可以用打印出leg,这是因为我们通过__proto__使他指向了dog,从而使Goldenretrieverdog一个隐藏属性leg

  • 当我们执行console.log(Goldenretrieverdog.leg)时,他会试图读取leg,当他发现自身没有时,就会会顺着Prototype引用,在dog中查找(自下而上)

  • 在这儿我们可以说 dog是Goldenretrieverdog的原型,或者说 Goldenretrieverdog的原型是从dog继承而来的

class继承

  • 类继承是一个类扩展另一个类的一种方式
    • 扩展另一个类的语法是:class Child extends Parent,Class 可以通过extends关键字实现继承
class Animal {
  constructor(name) {
    this.speed = 0;
    this.name = name;
  }
  run(speed) {
    this.speed = speed;
    alert(`${this.name} runs with speed ${this.speed}.`);
  }
  stop() {
    this.speed = 0;
    alert(`${this.name} stands still.`);
  }
}

let animal = new Animal("My animal");

class Rabbit extends Animal {
  hide() {
    alert(`${this.name} hides!`);
  }
}

let rabbit = new Rabbit("White Rabbit");

rabbit.run(5);  // 弹出White Rabbit runs with speed 5
  • 我们创建一个继承自 Animal 的 class Rabbit
  1. 当我们调用rabbit.run方法时,查找对象 rabbit有没有run
  2. 查找它的原型,即 Rabbit.prototype(还是没有run)。
  3. 查找Rabbit.prototype的原型,即Animal.prototype在这儿找到了run方法
  • 关键字extends使用了很好的旧的原型机制进行工作。它将Rabbit.prototype.Prototype设置为Animal.prototype。所以,如果在Rabbit.prototype 中找不到一个方法,JS就会从Animal.prototype中查找进行获取。