"prototype" 屿§å¨ JavaScript èªèº«çæ ¸å¿é¨åä¸è¢«å¹¿æ³å°åºç¨ãææçå
建æé 彿°é½ç¨å°äºå®ã
é¦å ï¼æä»¬å°ççåçååç详ç»ä¿¡æ¯ï¼ç¶åå¦ä¹ å¦ä½ä½¿ç¨å®ä¸ºå å»ºå¯¹è±¡æ·»å æ°åè½ã
Object.prototype
å妿们è¾åºä¸ä¸ªç©ºå¯¹è±¡ï¼
let obj = {};
alert( obj ); // "[object Object]" ?
çæå符串 "[object Object]" ç代ç å¨åªéï¼é£å°±æ¯ä¸ä¸ªå
建ç toString æ¹æ³ï¼ä½æ¯å®å¨åªéå¢ï¼obj æ¯ç©ºçï¼
â¦â¦ç¶èç®ççè¡¨è¾¾å¼ obj = {} å obj = new Object() æ¯ä¸ä¸ªææï¼å
¶ä¸ Object å°±æ¯ä¸ä¸ªå
建ç对象æé 彿°ï¼å
¶èªèº«ç prototype æåä¸ä¸ªå¸¦æ toString åå
¶ä»æ¹æ³çä¸ä¸ªå·¨å¤§ç对象ã
å°±åè¿æ ·ï¼
å½ new Object() 被è°ç¨ï¼æä¸ä¸ªåé¢é对象 {...} 被å建ï¼ï¼æç
§åé¢ç« è䏿们å¦ä¹ è¿çè§åï¼è¿ä¸ªå¯¹è±¡ç [[Prototype]] 屿§è¢«è®¾ç½®ä¸º Object.prototypeï¼
æä»¥ï¼ä¹åå½ obj.toString() 被è°ç¨æ¶ï¼è¿ä¸ªæ¹æ³æ¯ä» Object.prototype ä¸è·åçã
æä»¬å¯ä»¥è¿æ ·éªè¯å®ï¼
let obj = {};
alert(obj.__proto__ === Object.prototype); // true
alert(obj.toString === obj.__proto__.toString); //true
alert(obj.toString === Object.prototype.toString); //true
请注æå¨ Object.prototype 䏿¹çé¾ä¸æ²¡ææ´å¤ç [[Prototype]]ï¼
alert(Object.prototype.__proto__); // null
å ¶ä»å 建åå
å
¶ä»å
建对象ï¼å ArrayãDateãFunction åå
¶ä»ï¼é½å¨ prototype ä¸æè½½äºæ¹æ³ã
ä¾å¦ï¼å½æä»¬å建ä¸ä¸ªæ°ç» [1, 2, 3]ï¼å¨å
é¨ä¼é»è®¤ä½¿ç¨ new Array() æé å¨ãå æ¤ Array.prototype åæäºè¿ä¸ªæ°ç»ç prototypeï¼å¹¶ä¸ºè¿ä¸ªæ°ç»æä¾æ°ç»çæä½æ¹æ³ãè¿æ ·å
åçåå¨æçæ¯å¾é«çã
æç
§è§èï¼ææçå
建ååé¡¶ç«¯é½æ¯ Object.prototypeãè¿å°±æ¯ä¸ºä»ä¹æäººè¯´âä¸åé½ä»å¯¹è±¡ç»§æ¿èæ¥âã
ä¸é¢æ¯å®æ´ç示æå¾ï¼3 个å 建对象ï¼ï¼
让æä»¬æå¨éªè¯ååï¼
let arr = [1, 2, 3];
// å®ç»§æ¿èª Array.prototypeï¼
alert( arr.__proto__ === Array.prototype ); // true
// æ¥ä¸æ¥ç»§æ¿èª Object.prototypeï¼
alert( arr.__proto__.__proto__ === Object.prototype ); // true
// ååé¾ç顶端为 nullã
alert( arr.__proto__.__proto__.__proto__ ); // null
ä¸äºæ¹æ³å¨ååä¸å¯è½ä¼åçéå ï¼ä¾å¦ï¼Array.prototype æèªå·±ç toString æ¹æ³æ¥åä¸¾åºæ¥æ°ç»çææå
ç´ å¹¶ç¨éå·å鿝ä¸ä¸ªå
ç´ ã
let arr = [1, 2, 3]
alert(arr); // 1,2,3 <-- Array.prototype.toString çç»æ
æ£å¦æä»¬ä¹åçå°ç飿 ·ï¼Object.prototype 乿 toString æ¹æ³ï¼ä½æ¯ Array.prototype å¨ååé¾ä¸æ´è¿ï¼æä»¥æ°ç»å¯¹è±¡ååä¸çæ¹æ³ä¼è¢«ä½¿ç¨ã
æµè§å¨å
çå·¥å
·ï¼å Chrome å¼åè
æ§å¶å°ä¹ä¼æ¾ç¤ºç»§æ¿æ§ï¼å¯è½éè¦å¯¹å
å»ºå¯¹è±¡ä½¿ç¨ console.dirï¼ï¼
å
¶ä»å
建对象ä¹ä»¥åæ ·çæ¹å¼è¿è¡ãå³ä½¿æ¯å½æ° ââ å®ä»¬æ¯å
建æé å¨ Function ç对象ï¼å¹¶ä¸å®ä»¬çæ¹æ³ï¼call/apply åå
¶ä»ï¼é½åèª Function.prototypeã彿°ä¹æèªå·±ç toString æ¹æ³ã
function f() {}
alert(f.__proto__ == Function.prototype); // true
alert(f.__proto__.__proto__ == Object.prototype); // trueï¼ç»§æ¿èª Object
åºæ¬æ°æ®ç±»å
æå¤æçäºæ åçå¨åç¬¦ä¸²ãæ°ååå¸å°å¼ä¸ã
æ£å¦æä»¬è®°å¿ä¸ç飿 ·ï¼å®ä»¬å¹¶ä¸æ¯å¯¹è±¡ã使¯å¦ææä»¬è¯å¾è®¿é®å®ä»¬ç屿§ï¼é£ä¹ä¸´æ¶å
è£
å¨å¯¹è±¡å°ä¼éè¿å
建çæé å¨ StringãNumber å Boolean 被å建ãå®ä»¬æä¾ç»æä»¬æä½åç¬¦ä¸²ãæ°ååå¸å°å¼çæ¹æ³ç¶åæ¶å¤±ã
è¿äºå¯¹è±¡å¯¹æä»¬æ¥è¯´æ¯æ å½¢å°åå»ºåºæ¥çã大夿°å¼æé½ä¼å¯¹å
¶è¿è¡ä¼åï¼ä½æ¯è§èä¸æè¿°çå°±æ¯éè¿è¿ç§æ¹å¼ãè¿äºå¯¹è±¡çæ¹æ³ä¹é©»çå¨å®ä»¬ç prototype ä¸ï¼å¯ä»¥éè¿ String.prototypeãNumber.prototype å Boolean.prototype è¿è¡è·åã
null å undefined 没æå¯¹è±¡å
è£
å¨ç¹æ®å¼ null å undefined æ¯è¾ç¹æ®ãå®ä»¬æ²¡æå¯¹è±¡å
è£
å¨ï¼æä»¥å®ä»¬æ²¡ææ¹æ³å屿§ãå¹¶ä¸å®ä»¬ä¹æ²¡æç¸åºçååã
æ´æ¹åçåå
åççå忝å¯ä»¥è¢«ä¿®æ¹çãä¾å¦ï¼æä»¬å String.prototype 䏿·»å ä¸ä¸ªæ¹æ³ï¼è¿ä¸ªæ¹æ³å°å¯¹ææçåç¬¦ä¸²é½æ¯å¯ç¨çï¼
String.prototype.show = function() {
alert(this);
};
"BOOM!".show(); // BOOM!
å¨å¼åçè¿ç¨ä¸ï¼æä»¬å¯è½ä¼æ³è¦ä¸äºæ°çå å»ºæ¹æ³ï¼å¹¶ä¸æ³æå®ä»¬æ·»å å°åçååä¸ãä½è¿é常æ¯ä¸ä¸ªå¾ä¸å¥½çæ³æ³ã
å忝å
¨å±çï¼æä»¥å¾å®¹æé æå²çªã妿æä¸¤ä¸ªåºé½æ·»å äº String.prototype.show æ¹æ³ï¼é£ä¹å
¶ä¸çä¸ä¸ªæ¹æ³å°è¢«å¦ä¸ä¸ªè¦çã
æä»¥ï¼é常æ¥è¯´ï¼ä¿®æ¹åçåå被认为æ¯ä¸ä¸ªå¾ä¸å¥½çæ³æ³ã
å¨ç°ä»£ç¼ç¨ä¸ï¼åªæä¸ç§æ åµä¸å 许修æ¹åçååãé£å°±æ¯ polyfillingã
Polyfilling æ¯ä¸ä¸ªæ¯è¯ï¼è¡¨ç¤ºæä¸ªæ¹æ³å¨ JavaScript è§èä¸å·²åå¨ï¼ä½æ¯ç¹å®ç JavaScript 弿å°ä¸æ¯æè¯¥æ¹æ³ï¼é£ä¹æä»¬å¯ä»¥éè¿æå¨å®ç°å®ï¼å¹¶ç¨ä»¥å¡«å å 建ååã
ä¾å¦ï¼
if (!String.prototype.repeat) { // 妿è¿å¿æ²¡æè¿ä¸ªæ¹æ³
// é£å°±å¨ prototype 䏿·»å å®
String.prototype.repeat = function(n) {
// éå¤ä¼ å
¥çå符串 n 次
// å®é
ä¸ï¼å®ç°ä»£ç æ¯è¿ä¸ªè¦å¤æä¸äºï¼å®æ´çæ¹æ³å¯ä»¥å¨è§è䏿¾å°ï¼
// ä½å³ä½¿æ¯ä¸å¤å®ç¾ç polyfill ä¹å¸¸å¸¸è¢«è®¤ä¸ºæ¯è¶³å¤å¥½ç
return new Array(n + 1).join(this);
};
}
alert( "La".repeat(3) ); // LaLaLa
ä»ååä¸åç¨
å¨ è£ é¥°å¨æ¨¡å¼å转åï¼call/apply ä¸ç« ä¸ï¼æä»¬è®¨è®ºäºæ¹æ³åç¨ã
飿¯ææä»¬ä»ä¸ä¸ªå¯¹è±¡è·åä¸ä¸ªæ¹æ³ï¼å¹¶å°å ¶å¤å¶å°å¦ä¸ä¸ªå¯¹è±¡ã
ä¸äºåçååçæ¹æ³é常ä¼è¢«åç¨ã
ä¾å¦ï¼å¦ææä»¬è¦å建类æ°ç»å¯¹è±¡ï¼åå¯è½éè¦åå
¶ä¸å¤å¶ä¸äº Array æ¹æ³ã
ä¾å¦ï¼
let obj = {
0: "Hello",
1: "world!",
length: 2,
};
obj.join = Array.prototype.join;
alert( obj.join(',') ); // Hello,world!
ä¸é¢è¿æ®µä»£ç ææï¼æ¯å 为å
å»ºçæ¹æ³ join çå
é¨ç®æ³åªå
³å¿æ£ç¡®çç´¢å¼å length 屿§ãå®ä¸ä¼æ£æ¥è¿ä¸ªå¯¹è±¡æ¯å¦æ¯çæ£çæ°ç»ã许å¤å
å»ºæ¹æ³å°±æ¯è¿æ ·ã
å¦ä¸ç§æ¹å¼æ¯éè¿å° obj.__proto__ 设置为 Array.prototypeï¼è¿æ · Array ä¸çæææ¹æ³é½èªå¨å°å¯ä»¥å¨ obj ä¸ä½¿ç¨äºã
使¯å¦æ obj å·²ç»ä»å¦ä¸ä¸ªå¯¹è±¡è¿è¡äºç»§æ¿ï¼é£ä¹è¿ç§æ¹æ³å°±ä¸å¯è¡äºï¼è¯æ³¨ï¼å ä¸ºè¿æ ·ä¼è¦çæå·²æçç»§æ¿ãæ¤å¤ obj å
¶å®å·²ç»ä» Object è¿è¡äºç»§æ¿ï¼ä½æ¯ Array ä¹ç»§æ¿èª Objectï¼æä»¥æ¤å¤çæ¹æ³åç¨ä¸ä¼å½±å obj 对åæç»§æ¿çç»§æ¿ï¼å 为 obj éè¿ååé¾ä¾æ§ç»§æ¿äº Objectï¼ã请记ä½ï¼æä»¬ä¸æ¬¡åªè½ç»§æ¿ä¸ä¸ªå¯¹è±¡ã
æ¹æ³åç¨å¾çµæ´»ï¼å®å 许å¨éè¦æ¶æ··åæ¥èªä¸åå¯¹è±¡çæ¹æ³ã
æ»ç»
- ææçå
建对象é½éµå¾ªç¸åçæ¨¡å¼ï¼patternï¼ï¼
- æ¹æ³é½åå¨å¨ prototype ä¸ï¼
Array.prototypeãObject.prototypeãDate.prototypeçï¼ã - 对象æ¬èº«åªå卿°æ®ï¼æ°ç»å ç´ ãå¯¹è±¡å±æ§ãæ¥æï¼ã
- æ¹æ³é½åå¨å¨ prototype ä¸ï¼
- åå§æ°æ®ç±»åä¹å°æ¹æ³åå¨å¨å
è£
å¨å¯¹è±¡ç prototype ä¸ï¼
Number.prototypeãString.prototypeåBoolean.prototypeãåªæundefinedånull没æå è£ å¨å¯¹è±¡ã - å 建ååå¯ä»¥è¢«ä¿®æ¹æè¢«ç¨æ°çæ¹æ³å¡«å ã使¯ä¸å»ºè®®æ´æ¹å®ä»¬ãå¯ä¸å è®¸çæ åµå¯è½æ¯ï¼å½æä»¬æ·»å ä¸ä¸ªè¿æ²¡æè¢« JavaScript å¼ææ¯æï¼ä½å·²ç»è¢«å å ¥ JavaScript è§èçæ°æ åæ¶ï¼æå¯è½å è®¸è¿æ ·åã
è¯è®º
<code>æ ç¾æå ¥åªæå 个è¯ç代ç ï¼æå ¥å¤è¡ä»£ç å¯ä»¥ä½¿ç¨<pre>æ ç¾ï¼å¯¹äºè¶ è¿ 10 è¡ç代ç ï¼å»ºè®®ä½ ä½¿ç¨æ²ç®±ï¼plnkrï¼JSBinï¼codepenâ¦ï¼