å¨ç¼ç¨ä¸ï¼æä»¬ç»å¸¸ä¼æ³è·åå¹¶æ©å±ä¸äºä¸è¥¿ã
ä¾å¦ï¼æä»¬æä¸ä¸ª user 对象åå
¶å±æ§åæ¹æ³ï¼å¹¶å¸æå° admin å guest ä½ä¸ºåºäº user ç¨å ä¿®æ¹çåä½ãæä»¬æ³éç¨ user ä¸çå
容ï¼è䏿¯å¤å¶/éæ°å®ç°å®çæ¹æ³ï¼èåªæ¯å¨å
¶ä¹ä¸æå»ºä¸ä¸ªæ°ç对象ã
ååç»§æ¿ï¼Prototypal inheritanceï¼ è¿ä¸ªè¯è¨ç¹æ§è½å¤å¸®å©æä»¬å®ç°è¿ä¸éæ±ã
[[Prototype]]
å¨ JavaScript ä¸ï¼å¯¹è±¡æä¸ä¸ªç¹æ®çéè屿§ [[Prototype]]ï¼å¦è§è䏿å½åçï¼ï¼å®è¦ä¹ä¸º nullï¼è¦ä¹å°±æ¯å¯¹å¦ä¸ä¸ªå¯¹è±¡çå¼ç¨ã该对象被称为âååâï¼
å½æä»¬ä» object ä¸è¯»åä¸ä¸ªç¼ºå¤±ç屿§æ¶ï¼JavaScript ä¼èªå¨ä»ååä¸è·åè¯¥å±æ§ãå¨ç¼ç¨ä¸ï¼è¿è¢«ç§°ä¸ºâååç»§æ¿âãå¾å¿«ï¼æä»¬å°éè¿å¾å¤ç¤ºä¾æ¥å¦ä¹ æ¤ç±»ç»§æ¿ï¼ä»¥ååºäºæ¤ç±»ç»§æ¿çæ´ç«é
·çè¯è¨åè½ã
屿§ [[Prototype]] æ¯å
é¨çè䏿¯éèçï¼ä½æ¯è¿å¿æå¾å¤è®¾ç½®å®çæ¹å¼ã
å
¶ä¸ä¹ä¸å°±æ¯ä½¿ç¨ç¹æ®çåå __proto__ï¼å°±åè¿æ ·ï¼
let animal = {
eats: true
};
let rabbit = {
jumps: true
};
rabbit.__proto__ = animal; // 设置 rabbit.[[Prototype]] = animal
ç°å¨ï¼å¦ææä»¬ä» rabbit ä¸è¯»åä¸ä¸ªå®æ²¡æç屿§ï¼JavaScript ä¼èªå¨ä» animal ä¸è·åã
ä¾å¦ï¼
let animal = {
eats: true
};
let rabbit = {
jumps: true
};
rabbit.__proto__ = animal; // (*)
// ç°å¨è¿ä¸¤ä¸ªå±æ§æä»¬é½è½å¨ rabbit 䏿¾å°ï¼
alert( rabbit.eats ); // true (**)
alert( rabbit.jumps ); // true
è¿éç (*) è¡å° animal 设置为 rabbit çååã
å½ alert è¯å¾è¯»å rabbit.eats (**) æ¶ï¼å 为å®ä¸åå¨äº rabbit ä¸ï¼æä»¥ JavaScript ä¼é¡ºç [[Prototype]] å¼ç¨ï¼å¨ animal 䏿¥æ¾ï¼èªä¸èä¸ï¼ï¼
å¨è¿å¿æä»¬å¯ä»¥è¯´ âanimal æ¯ rabbit çååâï¼æè
说 ârabbit çååæ¯ä» animal ç»§æ¿èæ¥çâã
å æ¤ï¼å¦æ animal æè®¸å¤æç¨ç屿§åæ¹æ³ï¼é£ä¹å®ä»¬å°èªå¨å°åä¸ºå¨ rabbit ä¸å¯ç¨ãè¿ç§å±æ§è¢«ç§°ä¸ºâç»§æ¿âã
妿æä»¬å¨ animal 䏿ä¸ä¸ªæ¹æ³ï¼å®å¯ä»¥å¨ rabbit ä¸è¢«è°ç¨ï¼
let animal = {
eats: true,
walk() {
alert("Animal walk");
}
};
let rabbit = {
jumps: true,
__proto__: animal
};
// walk æ¹æ³æ¯ä»ååä¸è·å¾ç
rabbit.walk(); // Animal walk
è¯¥æ¹æ³æ¯èªå¨å°ä»ååä¸è·å¾çï¼åè¿æ ·ï¼
ååé¾å¯ä»¥å¾é¿ï¼
let animal = {
eats: true,
walk() {
alert("Animal walk");
}
};
let rabbit = {
jumps: true,
__proto__: animal
};
let longEar = {
earLength: 10,
__proto__: rabbit
};
// walk æ¯éè¿ååé¾è·å¾ç
longEar.walk(); // Animal walk
alert(longEar.jumps); // trueï¼ä» rabbitï¼
ç°å¨ï¼å¦ææä»¬ä» longEar ä¸è¯»åä¸äºå®ä¸åå¨çå
容ï¼JavaScript ä¼å
å¨ rabbit 䏿¥æ¾ï¼ç¶åå¨ animal 䏿¥æ¾ã
è¿éåªæä¸¤ä¸ªéå¶ï¼
- å¼ç¨ä¸è½å½¢æéç¯ã妿æä»¬è¯å¾ç»
__proto__èµå¼ä½ä¼å¯¼è´å¼ç¨å½¢æéç¯æ¶ï¼JavaScript 伿åºé误ã __proto__çå¼å¯ä»¥æ¯å¯¹è±¡ï¼ä¹å¯ä»¥æ¯nullãèå ¶ä»çç±»åé½ä¼è¢«å¿½ç¥ã
å½ç¶ï¼è¿å¯è½å¾æ¾èæè§ï¼ä½æ¯ä»ç¶è¦å¼ºè°ï¼åªè½æä¸ä¸ª [[Prototype]]ãä¸ä¸ªå¯¹è±¡ä¸è½ä»å
¶ä»ä¸¤ä¸ªå¯¹è±¡è·å¾ç»§æ¿ã
__proto__ æ¯ [[Prototype]] çå åå²åå èç䏿¥ç getter/setteråå¦è
常ç¯ä¸ä¸ªæ®éçé误ï¼å°±æ¯ä¸ç¥é __proto__ å [[Prototype]] çåºå«ã
请注æï¼__proto__ ä¸å
é¨ç [[Prototype]] ä¸ä¸æ ·ã__proto__ æ¯ [[Prototype]] ç getter/setterãç¨åï¼æä»¬å°çå°å¨ä»ä¹æ
åµä¸çè§£å®ä»¬å¾éè¦ï¼å¨å»ºç«å¯¹ JavaScript è¯è¨ççè§£æ¶ï¼è®©æä»¬ç¢è®°è¿ä¸ç¹ã
__proto__ 屿§æç¹è¿æ¶äºãå®çå卿¯åºäºåå²çåå ï¼ç°ä»£ç¼ç¨è¯è¨å»ºè®®æä»¬åºè¯¥ä½¿ç¨å½æ° Object.getPrototypeOf/Object.setPrototypeOf æ¥å代 __proto__ å» get/set ååãç¨åæä»¬å°ä»ç»è¿äºå½æ°ã
æ ¹æ®è§èï¼__proto__ å¿
é¡»ä»
åæµè§å¨ç¯å¢çæ¯æãä½å®é
ä¸ï¼å
æ¬æå¡ç«¯å¨å
çææç¯å¢é½æ¯æå®ï¼å æ¤æä»¬ä½¿ç¨å®æ¯é常å®å
¨çã
ç±äº __proto__ æ è®°å¨è§æä¸æ´å ææ¾ï¼æä»¥æä»¬å¨åé¢ç示ä¾ä¸å°ä½¿ç¨å®ã
åå ¥ä¸ä½¿ç¨åå
ååä» ç¨äºè¯»å屿§ã
对äºåå ¥/å 餿ä½å¯ä»¥ç´æ¥å¨å¯¹è±¡ä¸è¿è¡ã
å¨ä¸é¢ç示ä¾ä¸ï¼æä»¬å°ä¸º rabbit ç walk 屿§èµå¼ï¼
let animal = {
eats: true,
walk() {
/* rabbit ä¸ä¼ä½¿ç¨æ¤æ¹æ³ */
}
};
let rabbit = {
__proto__: animal
};
rabbit.walk = function() {
alert("Rabbit! Bounce-bounce!");
};
rabbit.walk(); // Rabbit! Bounce-bounce!
ä»ç°å¨å¼å§ï¼rabbit.walk() å°ç«å³å¨å¯¹è±¡ä¸æ¾å°è¯¥æ¹æ³å¹¶æ§è¡ï¼èæ é使ç¨ååï¼
访é®å¨ï¼accessorï¼å±æ§æ¯ä¸ä¸ªä¾å¤ï¼å 为èµå¼ï¼assignmentï¼æä½æ¯ç± setter 彿°å¤ççãå æ¤ï¼åå ¥æ¤ç±»å±æ§å®é ä¸ä¸è°ç¨å½æ°ç¸åã
ä¹å°±æ¯è¿ä¸ªåå ï¼æä»¥ä¸é¢è¿æ®µä»£ç ä¸ç admin.fullName è½å¤æ£å¸¸è¿è¡ï¼
let user = {
name: "John",
surname: "Smith",
set fullName(value) {
[this.name, this.surname] = value.split(" ");
},
get fullName() {
return `${this.name} ${this.surname}`;
}
};
let admin = {
__proto__: user,
isAdmin: true
};
alert(admin.fullName); // John Smith (*)
// setter triggers!
admin.fullName = "Alice Cooper"; // (**)
alert(admin.fullName); // Alice Cooperï¼admin çå
容被修æ¹äº
alert(user.fullName); // John Smithï¼user çå
å®¹è¢«ä¿æ¤äº
å¨ (*) è¡ä¸ï¼å±æ§ admin.fullName å¨åå user 䏿ä¸ä¸ª getterï¼å æ¤å®ä¼è¢«è°ç¨ãå¨ (**) è¡ä¸ï¼å±æ§å¨åå䏿ä¸ä¸ª setterï¼å æ¤å®ä¼è¢«è°ç¨ã
âthisâ çå¼
å¨ä¸é¢çä¾åä¸å¯è½ä¼åºç°ä¸ä¸ªæè¶£çé®é¢ï¼å¨ set fullName(value) ä¸ this ç弿¯ä»ä¹ï¼å±æ§ this.name å this.surname 被åå¨åªéï¼å¨ user è¿æ¯ adminï¼
çæ¡å¾ç®åï¼this æ ¹æ¬ä¸åååçå½±åã
æ 论å¨åªéæ¾å°æ¹æ³ï¼å¨ä¸ä¸ªå¯¹è±¡è¿æ¯å¨ååä¸ãå¨ä¸ä¸ªæ¹æ³è°ç¨ä¸ï¼this å§ç»æ¯ç¹ç¬¦å· . åé¢ç对象ã
å æ¤ï¼setter è°ç¨ admin.fullName= ä½¿ç¨ admin ä½ä¸º thisï¼è䏿¯ userã
è¿æ¯ä¸ä»¶é常éè¦çäºå¿ï¼å 为æä»¬å¯è½æä¸ä¸ªå¸¦æå¾å¤æ¹æ³ç大对象ï¼å¹¶ä¸è¿æä»å ¶ç»§æ¿ç对象ãå½ç»§æ¿ç对象è¿è¡ç»§æ¿çæ¹æ³æ¶ï¼å®ä»¬å°ä» ä¿®æ¹èªå·±çç¶æï¼èä¸ä¼ä¿®æ¹å¤§å¯¹è±¡çç¶æã
ä¾å¦ï¼è¿éç animal ä»£è¡¨âæ¹æ³åå¨âï¼rabbit å¨ä½¿ç¨å
¶ä¸çæ¹æ³ã
è°ç¨ rabbit.sleep() ä¼å¨ rabbit 对象ä¸è®¾ç½® this.isSleepingï¼
// animal æä¸äºæ¹æ³
let animal = {
walk() {
if (!this.isSleeping) {
alert(`I walk`);
}
},
sleep() {
this.isSleeping = true;
}
};
let rabbit = {
name: "White Rabbit",
__proto__: animal
};
// ä¿®æ¹ rabbit.isSleeping
rabbit.sleep();
alert(rabbit.isSleeping); // true
alert(animal.isSleeping); // undefinedï¼åå䏿²¡ææ¤å±æ§ï¼
ç»æç¤ºæå¾ï¼
妿æä»¬è¿æä» animal ç»§æ¿çå
¶ä»å¯¹è±¡ï¼å bird å snake çï¼å®ä»¬ä¹å°å¯ä»¥è®¿é® animal çæ¹æ³ã使¯ï¼æ¯ä¸ªæ¹æ³è°ç¨ä¸ç this 齿¯å¨è°ç¨æ¶ï¼ç¹ç¬¦å·åï¼è¯ä¼°ç对åºç对象ï¼è䏿¯ animalãå æ¤ï¼å½æä»¬å°æ°æ®åå
¥ this æ¶ï¼ä¼å°å
¶åå¨å°è¿äºå¯¹è±¡ä¸ã
æä»¥ï¼æ¹æ³æ¯å ±äº«çï¼ä½å¯¹è±¡ç¶æä¸æ¯ã
forâ¦in 循ç¯
for..in 循ç¯ä¹ä¼è¿ä»£ç»§æ¿ç屿§ã
ä¾å¦ï¼
let animal = {
eats: true
};
let rabbit = {
jumps: true,
__proto__: animal
};
// Object.keys åªè¿åèªå·±ç key
alert(Object.keys(rabbit)); // jumps
// for..in ä¼éåèªå·±ä»¥åç»§æ¿çé®
for(let prop in rabbit) alert(prop); // jumpsï¼ç¶åæ¯ eats
妿è¿ä¸æ¯æä»¬æ³è¦çï¼å¹¶ä¸æä»¬æ³æé¤ç»§æ¿ç屿§ï¼é£ä¹è¿å¿æä¸ä¸ªå
å»ºæ¹æ³ obj.hasOwnProperty(key)ï¼å¦æ obj å
·æèªå·±çï¼éç»§æ¿çï¼å为 key ç屿§ï¼åè¿å trueã
å æ¤ï¼æä»¬å¯ä»¥è¿æ»¤æç»§æ¿ç屿§ï¼æå¯¹å®ä»¬è¿è¡å ¶ä»æä½ï¼ï¼
let animal = {
eats: true
};
let rabbit = {
jumps: true,
__proto__: animal
};
for(let prop in rabbit) {
let isOwn = rabbit.hasOwnProperty(prop);
if (isOwn) {
alert(`Our: ${prop}`); // Our: jumps
} else {
alert(`Inherited: ${prop}`); // Inherited: eats
}
}
è¿éæä»¬æä»¥ä¸ç»§æ¿é¾ï¼rabbit ä» animal ä¸ç»§æ¿ï¼animal ä» Object.prototype ä¸ç»§æ¿ï¼å 为 animal æ¯å¯¹è±¡åé¢é {...}ï¼æä»¥è¿æ¯é»è®¤çç»§æ¿ï¼ï¼ç¶ååå䏿¯ nullï¼
注æï¼è¿æä¸ä»¶å¾æè¶£çäºå¿ãæ¹æ³ rabbit.hasOwnProperty æ¥èªåªå¿ï¼æä»¬å¹¶æ²¡æå®ä¹å®ãä»ä¸å¾ä¸çåå龿们å¯ä»¥çå°ï¼è¯¥æ¹æ³æ¯ Object.prototype.hasOwnProperty æä¾çãæ¢å¥è¯è¯´ï¼å®æ¯ç»§æ¿çã
â¦â¦å¦æ for..in 循ç¯ä¼ååºç»§æ¿ç屿§ï¼é£ä¸ºä»ä¹ hasOwnProperty 没æå eats å jumps 飿 ·åºç°å¨ for..in 循ç¯ä¸ï¼
çæ¡å¾ç®åï¼å®æ¯ä¸å¯æä¸¾çãå°±å Object.prototype çå
¶ä»å±æ§ï¼hasOwnProperty æ enumerable:false æ å¿ãå¹¶ä¸ for..in åªä¼ååºå¯æä¸¾ç屿§ãè¿å°±æ¯ä¸ºä»ä¹å®åå
¶ä½ç Object.prototype 屿§é½æªè¢«ååºã
å 乿æå
¶ä»é®/å¼è·åæ¹æ³ï¼ä¾å¦ Object.keys å Object.values çï¼é½ä¼å¿½ç¥ç»§æ¿ç屿§ã
å®ä»¬åªä¼å¯¹å¯¹è±¡èªèº«è¿è¡æä½ãä¸èè ç»§æ¿èªååç屿§ã
æ»ç»
- å¨ JavaScript ä¸ï¼ææçå¯¹è±¡é½æä¸ä¸ªéèç
[[Prototype]]屿§ï¼å®è¦ä¹æ¯å¦ä¸ä¸ªå¯¹è±¡ï¼è¦ä¹å°±æ¯nullã - æä»¬å¯ä»¥ä½¿ç¨
obj.__proto__访é®å®ï¼åå²éç䏿¥ç getter/setterï¼è¿å¿è¿æå ¶ä»æ¹æ³ï¼å¾å¿«æä»¬å°±ä¼è®²å°ï¼ã - éè¿
[[Prototype]]å¼ç¨ç对象被称为âååâã - 妿æä»¬æ³è¦è¯»å
objçä¸ä¸ªå±æ§æè è°ç¨ä¸ä¸ªæ¹æ³ï¼å¹¶ä¸å®ä¸åå¨ï¼é£ä¹ JavaScript å°±ä¼å°è¯å¨åå䏿¥æ¾å®ã - å/å 餿ä½ç´æ¥å¨å¯¹è±¡ä¸è¿è¡ï¼å®ä»¬ä¸ä½¿ç¨ååï¼åè®¾å®æ¯æ°æ®å±æ§ï¼ä¸æ¯ setterï¼ã
- 妿æä»¬è°ç¨
obj.method()ï¼èä¸methodæ¯ä»ååä¸è·åçï¼thisä»ç¶ä¼å¼ç¨objãå æ¤ï¼æ¹æ³å§ç»ä¸å½å对象ä¸èµ·ä½¿ç¨ï¼å³ä½¿æ¹æ³æ¯ç»§æ¿çã for..in循ç¯å¨å ¶èªèº«åç»§æ¿ç屿§ä¸è¿è¡è¿ä»£ãææå ¶ä»çé®/å¼è·åæ¹æ³ä» 对对象æ¬èº«èµ·ä½ç¨ã
è¯è®º
<code>æ ç¾æå ¥åªæå 个è¯ç代ç ï¼æå ¥å¤è¡ä»£ç å¯ä»¥ä½¿ç¨<pre>æ ç¾ï¼å¯¹äºè¶ è¿ 10 è¡ç代ç ï¼å»ºè®®ä½ ä½¿ç¨æ²ç®±ï¼plnkrï¼JSBinï¼codepenâ¦ï¼