.
.
extends
, Animal .
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed) {
this.speed = speed;
alert(`${this.name} / ${this.speed} .`);
}
stop() {
this.speed = 0;
alert(`${this.name} / .`);
}
}
let animal = new Animal("");
animal Animal .
Rabbit .
Rabbit Animal . .
class Child extends Parent .
Animal class Rabbit .
class Rabbit extends Animal {
hide() {
alert(`${this.name} / !`);
}
}
let rabbit = new Rabbit(" ");
rabbit.run(5); // / 5 .
rabbit.hide(); // / !
Rabbit rabbit.hide() Rabbit , rabbit.run() Animal .
extends . extends Rabbit.prototype.[[Prototype]] Animal.prototype . Rabbit.prototype Animal.prototype .
rabbit.run ( ).
-
rabbitrun.run. rabbitRabbit.prototype.hiderun.extendsRabbit.prototype,Animal.prototype.run.
. Date.prototype.[[Prototype]] Object.prototype . Date .
extends . 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()
// Animal stop() , .
}
}
, . . , .
super .
super.method(...),method.super(...), .
.
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed) {
this.speed = speed;
alert(`${this.name} ${this.speed} .`);
}
stop() {
this.speed = 0;
alert(`${this.name} .`);
}
}
class Rabbit extends Animal {
hide() {
alert(`${this.name} !`);
}
stop() {
super.stop(); // stop ,
this.hide(); // .
}
}
let rabbit = new Rabbit(" ");
rabbit.run(5); // 5 .
rabbit.stop(); // . !
Rabbit super.stop() stop .
super ..
Rabbit constructor .
class Rabbit extends Animal {
//
constructor(...args) {
super(...args);
}
}
constructor . constructor . .
Rabbit . 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(" ", 10); // ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
! . . ?
.
-
super(...),super(...).super(...)this.
super(...) ?
. .
' (derived constructor)' . [[ConstructorKind]]:"derived" .
new .
-
new,this. - , , .
this.
super . this .
this super() Rabbit .
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(" ", 10);
alert(rabbit.name); //
alert(rabbit.earLength); // 10
:
.
, .
.
.
.
.
class Animal {
name = 'animal'
constructor() {
alert(this.name); // (*)
}
}
class Rabbit extends Animal {
name = 'rabbit';
}
new Animal(); // animal
new Rabbit(); // animal
Animal Rabbit name .
Rabbit Rabbit Animal .
new Animal() new Rabbit() (*) alert animal .
, .
?
.
this.name this.showName() .
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 super() . Rabbit . Animal .
.
. .
getter setter .
super [[HomeObject]]
.
super .
super . .
super .
. " super ?" . " this . super.method() method ." . ?
. this this.__proto__.method method . .
. .
[[HomeObject]] . [[HomeObject]] . .
rabbit.__proto__ animal. rabbit.eat() this.__proto__ animal.eat() .
let animal = {
name: "",
eat() {
alert(`${this.name} / .`);
}
};
let rabbit = {
__proto__: animal,
name: "",
eat() {
// super.eat() .
this.__proto__.eat.call(this); // (*)
}
};
rabbit.eat(); // / .
(*) eat (animal) eat . .call(this). this.__proto__.eat() eat .call(this) .
.
. .
let animal = {
name: "",
eat() {
alert(`${this.name} / .`);
}
};
let rabbit = {
__proto__: animal,
eat() {
// call (animal) .
this.__proto__.eat.call(this); // (*)
}
};
let longEar = {
__proto__: rabbit,
eat() {
// longEar (rabbit) .
this.__proto__.eat.call(this); // (**)
}
};
longEar.eat(); // RangeError: Maximum call stack size exceeded
longEar.eat() !
longEar.eat() . (*) (**) . this longEar . . this .
(*) (**) this.__proto__ , rabbit . rabbit.eat .
.
-
longEar.eat()(**)rabbit.eat,thislongEar.// longEar.eat() this longEar. this.__proto__.eat.call(this) // (**) // . longEar.__proto__.eat.call(this) // longEar rabbit . rabbit.eat.call(this); -
rabbit.eat(*)thislongEarrabbit.eat.// rabbit.eat() this longEar. this.__proto__.eat.call(this) // (*) // . longEar.__proto__.eat.call(this) // longEar rabbit . rabbit.eat.call(this); -
rabbit.eat.
this .
[[HomeObject]]
. [[HomeObject]].
[[HomeObject]] .
super [[HomeObject]] .
[[HomeObject]] . .
let animal = {
name: "",
eat() { // animal.eat.[[HomeObject]] == animal
alert(`${this.name} / .`);
}
};
let rabbit = {
__proto__: animal,
name: "",
eat() { // rabbit.eat.[[HomeObject]] == rabbit
super.eat();
}
};
let longEar = {
__proto__: rabbit,
name: " ",
eat() { // longEar.eat.[[HomeObject]] == longEar
super.eat();
}
};
//
longEar.eat(); // / .
[[HomeObject]] . longEar.eat [[HomeObject]] this .
. this .
[[HomeObject]] . . [[HomeObject]] .
[[HomeObject]] super . super . . super .
super .
let animal = {
sayHi() {
console.log(` .`);
}
};
// rabbit animal .
let rabbit = {
__proto__: animal,
sayHi() {
super.sayHi();
}
};
let plant = {
sayHi() {
console.log(" .");
}
};
// tree plant .
let tree = {
__proto__: plant,
sayHi: rabbit.sayHi // (*)
};
tree.sayHi(); // . (?!?)
tree.sayHi() " ." . .
.
(*)tree.sayHirabbit.-
rabbit[[HomeObject]]rabbit,[[HomeObject]]. tree.sayHi()super.sayHi().rabbitanimalsuperanimalsayHi.
.
[[HomeObject]] . [[HomeObject]] method() . "method: function()" .
, .
(non-method syntax) . [[HomeObject]] .
let animal = {
eat: function() { // 'eat() {...' 'eat: function() {...' .
// ...
}
};
let rabbit = {
__proto__: animal,
eat: function() {
super.eat();
}
};
rabbit.eat(); // SyntaxError: 'super' keyword unexpected here ([[HomeObject]] )
- :
class Child extends ParentChild.prototype.__proto__Parent.prototype.
- :
thisChildsuper().
- :
Childsuper.method()Parent.
- super [[HomeObject]]
-
[[HomeObject]].super[[HomeObject]]. -
super.
-
:
-
thissuper.
<code>,<pre>. 10 plnkr, JSBin, codepen .