[ Web Proxy ]
URL:
Viewing: https://zh.javascript.info/class-inheritance [Back]  [Original]

:
Light themeDark theme
DanskEnglishEspaolFranaisIndonesiaItalianoTrkeOzbek

extends

class Animal

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");

animal class Animal

[]

class Rabbit

rabbit animal class Rabbit class Animal animal rabbit

class Child extends Parent

Animal class Rabbit

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

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

rabbit.run(5); // White Rabbit runs with speed 5.
rabbit.hide(); // White Rabbit hides!

class Rabbit rabbit.hide() Rabbit rabbit.run() Animal

extends Rabbit.prototype.[[Prototype]] Animal.prototype Rabbit.prototype JavaScript Animal.prototype

[]

rabbit.run JavaScript

  1. rabbit run
  2. Rabbit.prototype hide run
  3. extendsAnimal.prototype run

JavaScript Date.prototype.[[Prototype]] Object.prototype

extends

extends

function f(phrase) {
  return class {
    sayHi() { alert(phrase); }
  };
}

class User extends f("Hello") {}

new User().sayHi(); // Hello

class User f("Hello")

class Rabbit class Animal

Rabbit stop()

class Rabbit extends Animal {
  stop() {
    //  rabbit.stop()
    //  class Animal  stop()
  }
}

Class "super"

  • super.method(...)
  • super(...) constructor constructor

rabbit hide

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.`);
  }

}

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

  stop() {
    super.stop(); //  stop
    this.hide(); //  hide
  }
}

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

rabbit.run(5); // White Rabbit runs with speed 5.
rabbit.stop(); // White Rabbit stands still. White Rabbit hides!

Rabbit super.stop() Rabbit stop

super

super

class Rabbit extends Animal {
  stop() {
    setTimeout(() => super.stop(), 1000); // 1  stop
  }
}

super stop()

//  super
setTimeout(function() { super.stop() }, 1000);

constructor

constructor

Rabbit constructor

constructor constructor

class Rabbit extends Animal {
  //  constructor 
  constructor(...args) {
    super(...args);
  }
}

constructor constructor

Rabbit constructor name earLength

class Animal {
  constructor(name) {
    this.speed = 0;
    this.name = name;
  }
  // ...
}

class Rabbit extends Animal {

  constructor(name, earLength) {
    this.speed = 0;
    this.name = name;
    this.earLength = earLength;
  }

  // ...
}

// 
let rabbit = new Rabbit("White Rabbit", 10); // Error: this is not defined.

rabbit

constructor super(...) (!) this

JavaScript derived constructor [[ConstructorKind]]:"derived"

new

  • new this
  • constructor constructor

constructor super base constructor this

Rabbit constructor this super()

class Animal {

  constructor(name) {
    this.speed = 0;
    this.name = name;
  }

  // ...
}

class Rabbit extends Animal {

  constructor(name, earLength) {
    super(name);
    this.earLength = earLength;
  }

  // ...
}

// 
let rabbit = new Rabbit("White Rabbit", 10);
alert(rabbit.name); // White Rabbit
alert(rabbit.earLength); // 10

:

bugs ()

class Animal {
  name = 'animal';

  constructor() {
    alert(this.name); // (*)
  }
}

class Rabbit extends Animal {
  name = 'rabbit';
}

new Animal(); // animal
new Rabbit(); // animal

Rabbit Animal name

Rabbit Animal

new Animal() new Rabbit() (*) alert animal

this.showName() this.name

class Animal {
  showName() {  //  this.name = 'animal'
    alert('animal');
  }

  constructor() {
    this.showName(); //  alert(this.name);
  }
}

class Rabbit extends Animal {
  showName() {
    alert('rabbit');
  }
}

new Animal(); // animal
new Rabbit(); // rabbit

  • super()

Rabbit constructor() super(...args)

new Rabbit() super()Rabbit Animal

JavaScript

getter/setter

[[HomeObject]]

super

super

super

this super.method() method

this method this.__proto__.method

[[HomeObject]]

rabbit.__proto__ = animal rabbit.eat() this.__proto__ animal.eat()

let animal = {
  name: "Animal",
  eat() {
    alert(`${this.name} eats.`);
  }
};

let rabbit = {
  __proto__: animal,
  name: "Rabbit",
  eat() {
    //  super.eat() 
    this.__proto__.eat.call(this); // (*)
  }
};

rabbit.eat(); // Rabbit eats.

(*) animal eat.call(this) this.__proto__.eat() eat

alert

let animal = {
  name: "Animal",
  eat() {
    alert(`${this.name} eats.`);
  }
};

let rabbit = {
  __proto__: animal,
  eat() {
    // ...bounce around rabbit-style and call parent (animal) method
    this.__proto__.eat.call(this); // (*)
  }
};

let longEar = {
  __proto__: rabbit,
  eat() {
    // ...do something with long ears and call parent (rabbit) method
    this.__proto__.eat.call(this); // (**)
  }
};

longEar.eat(); // Error: Maximum call stack size exceeded

longEar.eat()

longEar.eat() (*) (**) this longEar this

(*) (**) this.__proto__ rabbit rabbit.eat

[]
  1. longEar.eat() (**) rabbit.eat this=longEar

    //  longEar.eat()  this = longEar
    this.__proto__.eat.call(this) // (**)
    // 
    longEar.__proto__.eat.call(this)
    // 
    rabbit.eat.call(this);
  2. rabbit.eat (*) this=longEar this.__proto__.eat rabbit.eat

    //  rabbit.eat()  this = longEar
    this.__proto__.eat.call(this) // (*)
    // 
    longEar.__proto__.eat.call(this)
    // 
    rabbit.eat.call(this);
  3. rabbit.eat

this

[[HomeObject]]

JavaScript [[HomeObject]]

[[HomeObject]]

super resolve

let animal = {
  name: "Animal",
  eat() {         // animal.eat.[[HomeObject]] == animal
    alert(`${this.name} eats.`);
  }
};

let rabbit = {
  __proto__: animal,
  name: "Rabbit",
  eat() {         // rabbit.eat.[[HomeObject]] == rabbit
    super.eat();
  }
};

let longEar = {
  __proto__: rabbit,
  name: "Long Ear",
  eat() {         // longEar.eat.[[HomeObject]] == longEar
    super.eat();
  }
};

// 
longEar.eat();  // Long Ear eats.

[[HomeObject]] longEar.eat [[HomeObject]] this

JavaScript this

[[HomeObject]] [[HomeObject]]

JavaScript [[HomeObject]] super super super

super

let animal = {
  sayHi() {
    alert(`I'm an animal`);
  }
};

// rabbit  animal
let rabbit = {
  __proto__: animal,
  sayHi() {
    super.sayHi();
  }
};

let plant = {
  sayHi() {
    alert("I'm a plant");
  }
};

// tree  plant
let tree = {
  __proto__: plant,
  sayHi: rabbit.sayHi // (*)
};

tree.sayHi();  // I'm an animal (?!?)

tree.sayHi() Im an animal

  • (*) tree.sayHi rabbit
  • [[HomeObject]] rabbit rabbit [[HomeObject]]
  • tree.sayHi() super.sayHi() rabbit animal

[]

[[HomeObject]] method() "method: function()"

JavaScript

non-method [[HomeObject]]

let animal = {
  eat: function() { //  eat() {...
    // ...
  }
};

let rabbit = {
  __proto__: animal,
  eat: function() {
    super.eat();
  }
};

rabbit.eat();  //  super [[HomeObject]]

  1. class Child extends Parent
    • Child.prototype.__proto__ Parent.prototype
  2. constructor
    • this Child constructor constructor super()
    • Child super.method() Parent
    • [[HomeObject]] / super
    • super

  • this super

: 5

Rabbit Animal

Rabbit

class Animal {

  constructor(name) {
    this.name = name;
  }

}

class Rabbit extends Animal {
  constructor(name) {
    this.name = name;
    this.created = Date.now();
  }
}

let rabbit = new Rabbit("White Rabbit"); // Error: this is not defined
alert(rabbit.name);

constructor super()

class Animal {

  constructor(name) {
    this.name = name;
  }

}

class Rabbit extends Animal {
  constructor(name) {
    super(name);
    this.created = Date.now();
  }
}

let rabbit = new Rabbit("White Rabbit"); // 
alert(rabbit.name); // White Rabbit
: 5

Clock

class Clock {
  constructor({ template }) {
    this.template = template;
  }

  render() {
    let date = new Date();

    let hours = date.getHours();
    if (hours < 10) hours = '0' + hours;

    let mins = date.getMinutes();
    if (mins < 10) mins = '0' + mins;

    let secs = date.getSeconds();
    if (secs < 10) secs = '0' + secs;

    let output = this.template
      .replace('h', hours)
      .replace('m', mins)
      .replace('s', secs);

    console.log(output);
  }

  stop() {
    clearInterval(this.timer);
  }

  start() {
    this.render();
    this.timer = setInterval(() => this.render(), 1000);
  }
}

Clock ExtendedClock precision ticks 10001

  • extended-clock.js
  • clock.js

class ExtendedClock extends Clock {
  constructor(options) {
    super(options);
    let { precision = 1000 } = options;
    this.precision = precision;
  }

  start() {
    this.render();
    this.timer = setInterval(() => this.render(), this.precision);
  }
};


Web Proxy Viewer  |  New URL  |  Original Page