ç±»ç»§æ¿æ¯ä¸ä¸ªç±»æ©å±å¦ä¸ä¸ªç±»çä¸ç§æ¹å¼ã
å æ¤ï¼æä»¬å¯ä»¥å¨ç°æåè½ä¹ä¸å建æ°åè½ã
â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 弿ä¼è¿è¡å¦ä¸æ£æ¥ï¼å¦å¾æç¤ºä»ä¸å°ä¸ï¼ï¼
- æ¥æ¾å¯¹è±¡
rabbitï¼æ²¡ærunï¼ã - æ¥æ¾å®çååï¼å³
Rabbit.prototypeï¼æhideï¼ä½æ²¡ærunï¼ã - æ¥æ¾å®çååï¼å³ï¼ç±äº
extendsï¼Animal.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ï¼å®ä»¬å¨ä¸åå°å¾ªç¯è°ç¨èªå·±ï¼è䏿¯å¨ååé¾ä¸åä¸å¯»æ¾æ¹æ³ã
è¿å¼ å¾ä»ç»äºåççæ åµï¼
-
å¨
longEar.eat()ä¸ï¼(**)è¿ä¸è¡è°ç¨rabbit.eatå¹¶ä¸ºå ¶æä¾this=longEarã// å¨ longEar.eat() 䏿们æ this = longEar this.__proto__.eat.call(this) // (**) // åæäº longEar.__proto__.eat.call(this) // ä¹å°±æ¯ rabbit.eat.call(this); -
ä¹åå¨
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); -
â¦â¦æä»¥
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() æ¾ç¤º âIâm 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]]ï¼
æ»ç»
- æ³è¦æ©å±ä¸ä¸ªç±»ï¼
class Child extends Parentï¼- è¿æå³ç
Child.prototype.__proto__å°æ¯Parent.prototypeï¼æä»¥æ¹æ³ä¼è¢«ç»§æ¿ã
- è¿æå³ç
- éåä¸ä¸ª constructorï¼
- å¨ä½¿ç¨
thisä¹åï¼æä»¬å¿ é¡»å¨Childç constructor ä¸å°ç¶ constructor è°ç¨ä¸ºsuper()ã
- å¨ä½¿ç¨
- éåä¸ä¸ªæ¹æ³ï¼
- æä»¬å¯ä»¥å¨ä¸ä¸ª
Childæ¹æ³ä¸ä½¿ç¨super.method()æ¥è°ç¨Parentæ¹æ³ã
- æä»¬å¯ä»¥å¨ä¸ä¸ª
- å
é¨ï¼
- æ¹æ³å¨å
é¨ç
[[HomeObject]]屿§ä¸è®°ä½äºå®ä»¬çç±»/对象ãè¿å°±æ¯superå¦ä½è§£æç¶æ¹æ³çã - å æ¤ï¼å°ä¸ä¸ªå¸¦æ
superçæ¹æ³ä»ä¸ä¸ªå¯¹è±¡å¤å¶å°å¦ä¸ä¸ªå¯¹è±¡æ¯ä¸å®å ¨çã
- æ¹æ³å¨å
é¨ç
è¡¥å ï¼
- ç®å¤´å½æ°æ²¡æèªå·±ç
thisæsuperï¼æä»¥å®ä»¬è½èå ¥å°å°±è¿çä¸ä¸æä¸ï¼åéæä¼¼çã
è¯è®º
<code>æ ç¾æå ¥åªæå 个è¯ç代ç ï¼æå ¥å¤è¡ä»£ç å¯ä»¥ä½¿ç¨<pre>æ ç¾ï¼å¯¹äºè¶ è¿ 10 è¡ç代ç ï¼å»ºè®®ä½ ä½¿ç¨æ²ç®±ï¼plnkrï¼JSBinï¼codepenâ¦ï¼