å¨è¿é¨åå 容ç第ä¸ç« ä¸ï¼æä»¬æå°äºè®¾ç½®ååçç°ä»£æ¹æ³ã
ä½¿ç¨ obj.__proto__ 设置æè¯»ååå被认为已ç»è¿æ¶ä¸ä¸æ¨è使ç¨ï¼deprecatedï¼äºï¼å·²ç»è¢«ç§»è³ JavaScript è§èçéå½ Bï¼æå³çä»
éç¨äºæµè§å¨ï¼ã
ç°ä»£çè·å/设置ååçæ¹æ³æï¼
- Object.getPrototypeOf(obj) ââ è¿å对象
objç[[Prototype]]ã - Object.setPrototypeOf(obj, proto) ââ å°å¯¹è±¡
objç[[Prototype]]设置为protoã
__proto__ ä¸è¢«å对çå¯ä¸çç¨æ³æ¯å¨å建æ°å¯¹è±¡æ¶ï¼å°å
¶ç¨ä½å±æ§ï¼{ __proto__: ... }ã
è½ç¶ï¼ä¹æä¸ç§ç¹æ®çæ¹æ³ï¼
- Object.create(proto, [descriptors]) ââ å©ç¨ç»å®ç
protoä½ä¸º[[Prototype]]åå¯éç屿§æè¿°æ¥å建ä¸ä¸ªç©ºå¯¹è±¡ã
ä¾å¦ï¼
let animal = {
eats: true
};
// å建ä¸ä¸ªä»¥ animal 为ååçæ°å¯¹è±¡
let rabbit = Object.create(animal); // ä¸ {__proto__: animal} ç¸å
alert(rabbit.eats); // true
alert(Object.getPrototypeOf(rabbit) === animal); // true
Object.setPrototypeOf(rabbit, {}); // å° rabbit çååä¿®æ¹ä¸º {}
Object.create æ¹æ³æ´å¼ºå¤§ï¼å ä¸ºå®æä¸ä¸ªå¯éç第äºåæ°ï¼å±æ§æè¿°å¨ã
æä»¬å¯ä»¥å¨æ¤å¤ä¸ºæ°å¯¹è±¡æä¾é¢å¤ç屿§ï¼å°±åè¿æ ·ï¼
let animal = {
eats: true
};
let rabbit = Object.create(animal, {
jumps: {
value: true
}
});
alert(rabbit.jumps); // true
æè¿°å¨çæ ¼å¼ä¸ 屿§æ å¿å屿§æè¿°ç¬¦ ä¸ç« ä¸æè®²ç䏿 ·ã
æä»¬å¯ä»¥ä½¿ç¨ Object.create æ¥å®ç°æ¯å¤å¶ for..in 循ç¯ä¸ç屿§æ´å¼ºå¤§ç对象å
éæ¹å¼ï¼
let clone = Object.create(
Object.getPrototypeOf(obj),
Object.getOwnPropertyDescriptors(obj)
);
æ¤è°ç¨å¯ä»¥å¯¹ obj è¿è¡çæ£åç¡®å°æ·è´ï¼å
æ¬ææç屿§ï¼å¯æä¸¾åä¸å¯æä¸¾çï¼æ°æ®å±æ§å setters/getters ââ å
æ¬ææå
容ï¼å¹¶å¸¦ææ£ç¡®ç [[Prototype]]ã
ååç®å²
æè¿ä¹å¤å¯ä»¥å¤ç [[Prototype]] çæ¹å¼ãåçäºä»ä¹ï¼ä¸ºä»ä¹ä¼è¿æ ·ï¼
è¿æ¯åå²åå ã
ååç»§æ¿ä»ä¸å¼å§å°±åå¨äºè¯è¨ä¸ï¼ä½ç®¡çå®çæ¹å¼éçæ¶é´çæ¨ç§»èæ¼åã
- æé 彿°ç
"prototype"屿§èªå¤ä»¥æ¥å°±èµ·ä½ç¨ãè¿æ¯ä½¿ç¨ç»å®ååå建对象çæå¤èçæ¹å¼ã - ä¹åï¼å¨ 2012 å¹´ï¼
Object.createåºç°å¨æ åä¸ã宿ä¾äºä½¿ç¨ç»å®ååå建对象çè½åã使²¡ææä¾ get/set å®çè½åãä¸äºæµè§å¨å®ç°äºéæ åç__proto__访é®å¨ï¼ä»¥ä¸ºå¼åè æä¾æ´å¤ççµæ´»æ§ã - ä¹åï¼å¨ 2015 å¹´ï¼
Object.setPrototypeOfåObject.getPrototypeOf被å å ¥å°æ åä¸ï¼æ§è¡ä¸__proto__ç¸åçåè½ãç±äº__proto__å®é ä¸å·²ç»å¨ææå°æ¹é½å¾å°äºå®ç°ï¼ä½å®å·²è¿æ¶ï¼æä»¥è¢«å å ¥å°è¯¥æ åçéä»¶ B ä¸ï¼å³ï¼å¨éæµè§å¨ç¯å¢ä¸ï¼å®çæ¯ææ¯å¯éçã - ä¹åï¼å¨ 2022 å¹´ï¼å®æ¹å
许å¨å¯¹è±¡åé¢é
{...}ä¸ä½¿ç¨__proto__ï¼ä»éå½ B ä¸ç§»åºæ¥äºï¼ï¼ä½ä¸è½ç¨ä½ getter/setterobj.__proto__ï¼ä»å¨éå½ B ä¸ï¼ã
为ä»ä¹è¦ç¨å½æ° getPrototypeOf/setPrototypeOf å代 __proto__ï¼
为ä»ä¹ __proto__ 被é¨å认å¯å¹¶å
è®¸å¨ {...} ä¸ä½¿ç¨ï¼ä½ä»ä¸è½ç¨ä½ getter/setterï¼
è¿æ¯ä¸ä¸ªæè¶£çé®é¢ï¼éè¦æä»¬ç解为ä»ä¹ __proto__ ä¸å¥½ã
å¾å¿«æä»¬å°±ä¼çå°çæ¡ã
[[Prototype]]仿æ¯ä¸æ¥è®²ï¼æä»¬å¯ä»¥å¨ä»»ä½æ¶å get/set [[Prototype]]ã使¯é常æä»¬åªå¨åå»ºå¯¹è±¡çæ¶å设置å®ä¸æ¬¡ï¼èªé£ä¹åä¸åä¿®æ¹ï¼rabbit ç»§æ¿èª animalï¼ä¹åä¸åæ´æ¹ã
å¹¶ä¸ï¼JavaScript 弿坹æ¤è¿è¡äºé«åº¦ä¼åãç¨ Object.setPrototypeOf æ obj.__proto__= â峿¶âæ´æ¹å忝ä¸ä¸ªéå¸¸ç¼æ
¢çæä½ï¼å 为å®ç ´åäºå¯¹è±¡å±æ§è®¿é®æä½çå
é¨ä¼åãå æ¤ï¼é¤éä½ ç¥éèªå·±å¨åä»ä¹ï¼æè
JavaScript çæ§è¡éåº¦å¯¹ä½ æ¥è¯´å®å
¨ä¸éè¦ï¼å¦å请é¿å
使ç¨å®ã
"Very plain" objects
æä»¬ç¥éï¼å¯¹è±¡å¯ä»¥ç¨ä½å ³èæ°ç»ï¼associative arraysï¼æ¥åå¨é®/å¼å¯¹ã
â¦â¦ä½æ¯å¦ææä»¬å°è¯å¨å
¶ä¸åå¨ ç¨æ·æä¾ç é®ï¼ä¾å¦ï¼ä¸ä¸ªç¨æ·è¾å
¥çåå
¸ï¼ï¼æä»¬å¯ä»¥åç°ä¸ä¸ªæè¶£çå°æ
éï¼ææçé®é½æ£å¸¸å·¥ä½ï¼é¤äº "__proto__"ã
çä¸ä¸è¿ä¸ªä¾åï¼
let obj = {};
let key = prompt("What's the key?", "__proto__");
obj[key] = "some value";
alert(obj[key]); // [object Object]ï¼å¹¶ä¸æ¯ "some value"ï¼
è¿éå¦æç¨æ·è¾å
¥ __proto__ï¼é£ä¹å¨ç¬¬åè¡çèµå¼ä¼è¢«å¿½ç¥ï¼
对äºéå¼åè
æ¥è¯´ï¼è¿è¯å®å¾ä»¤äººæè®¶ï¼ä½å¯¹æä»¬æ¥è¯´å´æ¯å¯ä»¥çè§£çã__proto__ 屿§å¾ç¹æ®ï¼å®å¿
é¡»æ¯ä¸ä¸ªå¯¹è±¡æè
nullãå符串ä¸è½æä¸ºååãè¿å°±æ¯ä¸ºä»ä¹å°å符串èµå¼ç» __proto__ ä¼è¢«å¿½ç¥ã
使们䏿¯ æç® å®ç°è¿ç§è¡ä¸ºï¼å¯¹å§ï¼æä»¬æ³è¦åå¨é®å¼å¯¹ï¼ç¶èé®å为 "__proto__" çé®å¼å¯¹æ²¡æè¢«æ£ç¡®åå¨ãæä»¥è¿æ¯ä¸ä¸ª bugã
è¿éçåæå¹¶æ²¡æå¾ä¸¥éãä½å¨å
¶ä»æ
åµä¸ï¼æä»¬å¯è½ä¼å¨ obj ä¸åå¨å¯¹è±¡è䏿¯å符串ï¼åååç¡®å®ä¼è¢«æ¹åãç»æï¼æ§è¡å°ä»¥å®å
¨ææ³ä¸å°çæ¹å¼åºéã
æå¯æçæ¯ ââ é常å¼åè å®å ¨ä¸ä¼èèå°è¿ä¸ç¹ãè¿è®©æ¤ç±» bug å¾é¾è¢«åç°ï¼çè³åææ¼æ´ï¼å°¤å ¶æ¯å¨ JavaScript 被ç¨å¨æå¡ç«¯çæ¶åã
对 obj.toString è¿è¡èµå¼æ¶ä¹å¯è½åçææ³ä¸å°çäºæ
ï¼å ä¸ºå®æ¯ä¸ä¸ªå
建çå¯¹è±¡æ¹æ³ã
æä»¬æä¹é¿å è¿æ ·çé®é¢å¢ï¼
é¦å
ï¼æä»¬å¯ä»¥æ¹ç¨ Map æ¥ä»£æ¿æ®é对象è¿è¡åå¨ï¼è¿æ ·ä¸åé½è¿åèè§£ï¼
let map = new Map();
let key = prompt("What's the key?", "__proto__");
map.set(key, "some value");
alert(map.get(key)); // "some value"ï¼ç¬¦å颿ï¼
â¦â¦ä½ Object è¯æ³é常æ´å¸å¼äººï¼å ä¸ºå®æ´ç®æ´ã
幸è¿çæ¯ï¼æä»¬ å¯ä»¥ 使ç¨å¯¹è±¡ï¼å 为 JavaScript è¯è¨çå¶é è å¾ä¹ 以åå°±èèè¿è¿ä¸ªé®é¢ã
æ£å¦æä»¬æç¥éçï¼__proto__ 䏿¯å¯¹è±¡ç屿§ï¼èæ¯ Object.prototype ç访é®å¨å±æ§ï¼
å æ¤ï¼å¦æ obj.__proto__ 被读åæè
èµå¼ï¼é£ä¹å¯¹åºç getter/setter ä¼è¢«ä»å®çååä¸è°ç¨ï¼å®ä¼ set/get [[Prototype]]ã
å°±å卿¬é¨åæç¨çå¼å¤´æè¯´ç飿 ·ï¼__proto__ æ¯ä¸ç§è®¿é® [[Prototype]] çæ¹å¼ï¼è䏿¯ [[prototype]] æ¬èº«ã
ç°å¨ï¼æä»¬æ³è¦å°ä¸ä¸ªå¯¹è±¡ç¨ä½å ³èæ°ç»ï¼å¹¶ä¸æè±æ¤ç±»é®é¢ï¼æä»¬å¯ä»¥ä½¿ç¨ä¸äºå°æå·§ï¼
let obj = Object.create(null);
// æè
ï¼obj = { __proto__: null }
let key = prompt("What's the key?", "__proto__");
obj[key] = "some value";
alert(obj[key]); // "some value"
Object.create(null) å建äºä¸ä¸ªç©ºå¯¹è±¡ï¼è¿ä¸ªå¯¹è±¡æ²¡æååï¼[[Prototype]] æ¯ nullï¼ï¼
å æ¤ï¼å®æ²¡æç»§æ¿ __proto__ ç getter/setter æ¹æ³ãç°å¨ï¼å®è¢«ä½ä¸ºæ£å¸¸çæ°æ®å±æ§è¿è¡å¤çï¼å æ¤ä¸é¢çè¿ä¸ªç¤ºä¾è½å¤æ£å¸¸å·¥ä½ã
æä»¬å¯ä»¥æè¿æ ·ç对象称为 âvery plainâ æ âpure dictionaryâ 对象ï¼å 为å®ä»¬çè³æ¯éå¸¸çæ®é对象ï¼plain objectï¼{...} è¿è¦ç®åã
ç¼ºç¹æ¯è¿æ ·ç对象没æä»»ä½å
建çå¯¹è±¡çæ¹æ³ï¼ä¾å¦ toStringï¼
let obj = Object.create(null);
alert(obj); // Error (no toString)
â¦â¦ä½æ¯å®ä»¬éå¸¸å¯¹å ³èæ°ç»èè¨è¿æ¯å¾å好ã
请注æï¼å¤§å¤æ°ä¸å¯¹è±¡ç¸å
³çæ¹æ³é½æ¯ Object.something(...)ï¼ä¾å¦ Object.keys(obj) ââ å®ä»¬ä¸å¨ prototype ä¸ï¼å æ¤å¨ âvery plainâ 对象ä¸å®ä»¬è¿æ¯å¯ä»¥ç»§ç»ä½¿ç¨ï¼
let chineseDictionary = Object.create(null);
chineseDictionary.hello = "ä½ å¥½";
chineseDictionary.bye = "åè§";
alert(Object.keys(chineseDictionary)); // hello,bye
æ»ç»
-
è¦ä½¿ç¨ç»å®çååå建对象ï¼ä½¿ç¨ï¼
- åé¢éè¯æ³ï¼
{ __proto__: ... }ï¼å 许æå®å¤ä¸ªå±æ§ - æ Object.create(proto, [descriptors])ï¼å 许æå®å±æ§æè¿°ç¬¦ã
Object.createæä¾äºä¸ç§ç®åçæ¹å¼æ¥æµ æ·è´å¯¹è±¡åå ¶ææå±æ§æè¿°ç¬¦ï¼descriptorsï¼ãlet clone = Object.create(Object.getPrototypeOf(obj), Object.getOwnPropertyDescriptors(obj)); - åé¢éè¯æ³ï¼
-
设置å访é®ååçç°ä»£æ¹æ³æï¼
- Object.getPrototypeOf(obj) ââ è¿å对象
objç[[Prototype]]ï¼ä¸__proto__ç getter ç¸åï¼ã - Object.setPrototypeOf(obj, proto) ââ å°å¯¹è±¡
objç[[Prototype]]设置为protoï¼ä¸__proto__ç setter ç¸åï¼ã
- Object.getPrototypeOf(obj) ââ è¿å对象
-
䏿¨è使ç¨å 建ç
__proto__getter/setter è·å/设置ååï¼å®ç°å¨å¨ ECMA è§èçéå½ B ä¸ã -
æä»¬è¿ä»ç»äºä½¿ç¨
Object.create(null)æ{__proto__: null}åå»ºçæ ååç对象ãè¿äºå¯¹è±¡è¢«ç¨ä½åå ¸ï¼ä»¥åå¨ä»»æï¼å¯è½æ¯ç¨æ·çæçï¼é®ã
é常ï¼å¯¹è±¡ä¼ä»
Object.prototypeç»§æ¿å å»ºçæ¹æ³å__proto__getter/setterï¼ä¼å ç¨ç¸åºçé®ï¼ä¸å¯è½ä¼å¯¼è´å¯ä½ç¨ãåå为nullæ¶ï¼å¯¹è±¡æçæ£æ¯ç©ºçã
è¯è®º
<code>æ ç¾æå ¥åªæå 个è¯ç代ç ï¼æå ¥å¤è¡ä»£ç å¯ä»¥ä½¿ç¨<pre>æ ç¾ï¼å¯¹äºè¶ è¿ 10 è¡ç代ç ï¼å»ºè®®ä½ ä½¿ç¨æ²ç®±ï¼plnkrï¼JSBinï¼codepenâ¦ï¼