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
-
rabbitrun -
Rabbit.prototypehiderun -
extendsAnimal.prototyperun
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
superconstructor
constructor
Rabbit 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
-
newthis - 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
-
longEar.eat()(**)rabbit.eatthis=longEar// longEar.eat() this = longEar this.__proto__.eat.call(this) // (**) // longEar.__proto__.eat.call(this) // rabbit.eat.call(this); -
rabbit.eat(*)this=longEarthis.__proto__.eatrabbit.eat// rabbit.eat() this = longEar this.__proto__.eat.call(this) // (*) // longEar.__proto__.eat.call(this) // rabbit.eat.call(this); -
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.sayHirabbit -
[[HomeObject]]rabbitrabbit[[HomeObject]] tree.sayHi()super.sayHi()rabbitanimal
[[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]]
class Child extends Parent-
Child.prototype.__proto__Parent.prototype
-
- constructor
-
thisChildconstructor constructorsuper()
-
-
-
Childsuper.method()Parent
-
-
-
[[HomeObject]]/super -
super
-
-
thissuper
<code><pre>10 plnkrJSBincodepen