å½å¯¹è±¡ç¸å obj1 + obj2ï¼ç¸å obj1 - obj2ï¼æè
ä½¿ç¨ alert(obj) æå°æ¶ä¼åçä»ä¹ï¼
JavaScript ä¸å 许èªå®ä¹è¿ç®ç¬¦å¯¹å¯¹è±¡çå¤çæ¹å¼ãä¸å ¶ä»ä¸äºç¼ç¨è¯è¨ï¼Rubyï¼C++ï¼ä¸åï¼æä»¬æ æ³å®ç°ç¹æ®ç对象å¤çæ¹æ³æ¥å¤çå æ³ï¼æå ¶ä»è¿ç®ï¼ã
卿¤ç±»è¿ç®çæ åµä¸ï¼å¯¹è±¡ä¼è¢«èªå¨è½¬æ¢ä¸ºåå§å¼ï¼ç¶å对è¿äºåå§å¼è¿è¡è¿ç®ï¼å¹¶å¾å°è¿ç®ç»æï¼ä¹æ¯ä¸ä¸ªåå§å¼ï¼ã
è¿æ¯ä¸ä¸ªéè¦çéå¶ï¼å 为 obj1 + obj2ï¼æè
å
¶ä»æ°å¦è¿ç®ï¼çç»æä¸è½æ¯å¦ä¸ä¸ªå¯¹è±¡ï¼
ä¾å¦ï¼æä»¬æ æ³ä½¿ç¨å¯¹è±¡æ¥è¡¨ç¤ºåéæç©éµï¼æå®ä»¬ç¸å å¹¶ææå¾å°ä¸ä¸ªâæ»åâåéä½ä¸ºç»æãè¿æ ·çæ³æ³æ¯è¡ä¸éçã
å æ¤ï¼ç±äºæä»¬ä»ææ¯ä¸æ æ³å®ç°æ¤ç±»è¿ç®ï¼æä»¥å¨å®é 项ç®ä¸ä¸åå¨å¯¹å¯¹è±¡çæ°å¦è¿ç®ãå¦æä½ åç°æï¼é¤äºæå°æ°ä¾å¤ï¼é常æ¯åéäºã
æ¬æå°ä»ç»å¯¹è±¡æ¯å¦ä½è½¬æ¢ä¸ºåå§å¼çï¼ä»¥åå¦ä½å¯¹å ¶è¿è¡èªå®ä¹ã
æä»¬æä¸¤ä¸ªç®çï¼
- 让æä»¬å¨éå°ç±»ä¼¼ç对对象è¿è¡æ°å¦è¿ç®çç¼ç¨é误æ¶ï¼è½å¤æ´å çè§£å°åºåçäºä»ä¹ã
- 乿ä¾å¤ï¼è¿äºæä½ä¹å¯ä»¥æ¯å¯è¡çãä¾å¦æ¥æç¸åææ¯è¾ï¼
Date对象ï¼ãæä»¬ç¨åä¼éå°å®ä»¬ã
转æ¢è§å
å¨ ç±»åè½¬æ¢ ä¸ç« ä¸ï¼æä»¬å·²ç»çå°äºæ°åãå符串åå¸å°è½¬æ¢çè§åã使¯æä»¬æ²¡æè®²å¯¹è±¡ç转æ¢è§åãç°å¨æä»¬å·²ç»ææ¡äºæ¹æ³ï¼methodï¼å symbol çç¸å ³ç¥è¯ï¼å¯ä»¥å¼å§å¦ä¹ 对象åå§å¼è½¬æ¢äºã
- 没æè½¬æ¢ä¸ºå¸å°å¼ãææç对象å¨å¸å°ä¸ä¸æï¼contextï¼ä¸å为
trueï¼å°±è¿ä¹ç®åãåªæåç¬¦ä¸²åæ°å转æ¢ã - æ°å转æ¢åçå¨å¯¹è±¡ç¸åæåºç¨æ°å¦å½æ°æ¶ãä¾å¦ï¼
Date对象ï¼å°å¨ æ¥æåæ¶é´ ä¸ç« ä¸ä»ç»ï¼å¯ä»¥ç¸åï¼date1 - date2çç»ææ¯ä¸¤ä¸ªæ¥æä¹é´çå·®å¼ã - è³äºåç¬¦ä¸²è½¬æ¢ ââ é常åç卿们å
alert(obj)è¿æ ·è¾åºä¸ä¸ªå¯¹è±¡å类似çä¸ä¸æä¸ã
æä»¬å¯ä»¥ä½¿ç¨ç¹æ®çå¯¹è±¡æ¹æ³ï¼èªå·±å®ç°åç¬¦ä¸²åæ°åç转æ¢ã
ç°å¨è®©æä»¬ä¸èµ·æ¢ç©¶ææ¯ç»èï¼å ä¸ºè¿æ¯æ·±å ¥è®¨è®ºè¯¥ä¸»é¢çå¯ä¸æ¹å¼ã
hint
JavaScript æ¯å¦ä½å³å®åºç¨åªç§è½¬æ¢çï¼
ç±»å转æ¢å¨åç§æ åµä¸æä¸ç§åä½ãå®ä»¬è¢«ç§°ä¸º âhintâï¼å¨ è§è æè¿°ï¼
"string"-
对象å°å符串ç转æ¢ï¼å½æä»¬å¯¹ææä¸ä¸ªå符串ç对象æ§è¡æä½æ¶ï¼å¦ âalertâï¼
// è¾åº alert(obj); // å°å¯¹è±¡ä½ä¸ºå±æ§é® anotherObj[obj] = 123; "number"-
å¯¹è±¡å°æ°åç转æ¢ï¼ä¾å¦å½æä»¬è¿è¡æ°å¦è¿ç®æ¶ï¼
// æ¾å¼è½¬æ¢ let num = Number(obj); // æ°å¦è¿ç®ï¼é¤äºäºå å æ³ï¼ let n = +obj; // ä¸å å æ³ let delta = date1 - date2; // å°äº/大äºçæ¯è¾ let greater = user1 > user2;大夿°å å»ºçæ°å¦å½æ°ä¹å æ¬è¿ç§è½¬æ¢ã
"default"-
å¨å°æ°æ åµä¸åçï¼å½è¿ç®ç¬¦âä¸ç¡®å®âææå¼çç±»åæ¶ã
ä¾å¦ï¼äºå å æ³
+å¯ç¨äºå符串ï¼è¿æ¥ï¼ï¼ä¹å¯ä»¥ç¨äºæ°åï¼ç¸å ï¼ãå æ¤ï¼å½äºå å æ³å¾å°å¯¹è±¡ç±»åçåæ°æ¶ï¼å®å°ä¾æ®"default"hint æ¥å¯¹å ¶è¿è¡è½¬æ¢ãæ¤å¤ï¼å¦æå¯¹è±¡è¢«ç¨äºä¸åç¬¦ä¸²ãæ°åæ symbol è¿è¡
==æ¯è¾ï¼è¿æ¶å°åºåºè¯¥è¿è¡åªç§è½¬æ¢ä¹ä¸æ¯å¾æç¡®ï¼å æ¤ä½¿ç¨"default"hintã// äºå å æ³ä½¿ç¨é»è®¤ hint let total = obj1 + obj2; // obj == number 使ç¨é»è®¤ hint if (user == 1) { ... };å
<å>è¿æ ·çå°äº/å¤§äºæ¯è¾è¿ç®ç¬¦ï¼ä¹å¯ä»¥åæ¶ç¨äºåç¬¦ä¸²åæ°åãä¸è¿ï¼å®ä»¬ä½¿ç¨ ânumberâ hintï¼è䏿¯ âdefaultâãè¿æ¯åå²åå ã
ä¸é¢è¿äºè§åçèµ·æ¥æ¯è¾å¤æï¼ä½å¨å®è·µä¸å ¶å®æºç®åçã
é¤äºä¸ç§æ
åµï¼Date å¯¹è±¡ï¼æä»¬ç¨åä¼è®²å°ï¼ä¹å¤ï¼ææå
建对象é½ä»¥å "number" ç¸åçæ¹å¼å®ç° "default" 转æ¢ãæä»¬ä¹å¯ä»¥è¿æ ·åã
å°½ç®¡å¦æ¤ï¼äºè§£ä¸è¿°ç 3 个 hint è¿æ¯å¾éè¦çï¼å¾å¿«ä½ 就伿ç½ä¸ºä»ä¹è¿æ ·è¯´ã
为äºè¿è¡è½¬æ¢ï¼JavaScript å°è¯æ¥æ¾å¹¶è°ç¨ä¸ä¸ªå¯¹è±¡æ¹æ³ï¼
- è°ç¨
obj[Symbol.toPrimitive](hint)ââ 带æ symbol é®Symbol.toPrimitiveï¼ç³»ç» symbolï¼çæ¹æ³ï¼å¦æè¿ä¸ªæ¹æ³åå¨çè¯ï¼ - å¦åï¼å¦æ hint æ¯
"string"ââ å°è¯è°ç¨obj.toString()æobj.valueOf()ï¼æ 论åªä¸ªåå¨ã - å¦åï¼å¦æ hint æ¯
"number"æ"default"ââ å°è¯è°ç¨obj.valueOf()æobj.toString()ï¼æ 论åªä¸ªåå¨ã
Symbol.toPrimitive
æä»¬ä»ç¬¬ä¸ä¸ªæ¹æ³å¼å§ãæä¸ä¸ªå为 Symbol.toPrimitive çå
建 symbolï¼å®è¢«ç¨æ¥ç»è½¬æ¢æ¹æ³å½åï¼åè¿æ ·ï¼
obj[Symbol.toPrimitive] = function(hint) {
// è¿éæ¯å°æ¤å¯¹è±¡è½¬æ¢ä¸ºåå§å¼ç代ç
// å®å¿
é¡»è¿åä¸ä¸ªåå§å¼
// hint = "string"ã"number" æ "default" ä¸çä¸ä¸ª
}
妿 Symbol.toPrimitive æ¹æ³åå¨ï¼åå®ä¼è¢«ç¨äºææ hintï¼æ éæ´å¤å
¶ä»æ¹æ³ã
ä¾å¦ï¼è¿é user 对象å®ç°äºå®ï¼
let user = {
name: "John",
money: 1000,
[Symbol.toPrimitive](hint) {
alert(`hint: ${hint}`);
return hint == "string" ? `{name: "${this.name}"}` : this.money;
}
};
// è½¬æ¢æ¼ç¤ºï¼
alert(user); // hint: string -> {name: "John"}
alert(+user); // hint: number -> 1000
alert(user + 500); // hint: default -> 1500
ä»ä»£ç 䏿们å¯ä»¥çå°ï¼æ ¹æ®è½¬æ¢çä¸åï¼user åæä¸ä¸ªèªæè¿°å符串æè
ä¸ä¸ªéé¢ãuser[Symbol.toPrimitive] æ¹æ³å¤çäºææçè½¬æ¢æ
åµã
toString/valueOf
å¦ææ²¡æ Symbol.toPrimitiveï¼é£ä¹ JavaScript å°å°è¯å¯»æ¾ toString å valueOf æ¹æ³ï¼
- 对äº
"string"hintï¼è°ç¨toStringæ¹æ³ï¼å¦æå®ä¸åå¨ï¼åè°ç¨valueOfæ¹æ³ï¼å æ¤ï¼å¯¹äºå符串转æ¢ï¼ä¼å è°ç¨toStringï¼ã - 对äºå
¶ä» hintï¼è°ç¨
valueOfæ¹æ³ï¼å¦æå®ä¸åå¨ï¼åè°ç¨toStringæ¹æ³ï¼å æ¤ï¼å¯¹äºæ°å¦è¿ç®ï¼ä¼å è°ç¨valueOfæ¹æ³ï¼ã
toString å valueOf æ¹æ³å¾æ©å·±æäºãå®ä»¬ä¸æ¯ symbolï¼é£æ¶åè¿æ²¡æ symbol è¿ä¸ªæ¦å¿µï¼ï¼èæ¯â常è§çâå符串å½åçæ¹æ³ãå®ä»¬æä¾äºä¸ç§å¯éçâèæ´¾âçå®ç°è½¬æ¢çæ¹æ³ã
è¿äºæ¹æ³å¿
é¡»è¿åä¸ä¸ªåå§å¼ã妿 toString æ valueOf è¿åäºä¸ä¸ªå¯¹è±¡ï¼é£ä¹è¿åå¼ä¼è¢«å¿½ç¥ï¼åè¿éæ²¡ææ¹æ³çæ¶åç¸åï¼ã
é»è®¤æ
åµä¸ï¼æ®é对象å
·æ toString å valueOf æ¹æ³ï¼
toStringæ¹æ³è¿åä¸ä¸ªå符串"[object Object]"ãvalueOfæ¹æ³è¿å对象èªèº«ã
ä¸é¢æ¯ä¸ä¸ªç¤ºä¾ï¼
let user = {name: "John"};
alert(user); // [object Object]
alert(user.valueOf() === user); // true
æä»¥ï¼å¦ææä»¬å°è¯å°ä¸ä¸ªå¯¹è±¡å½åå符串æ¥ä½¿ç¨ï¼ä¾å¦å¨ alert ä¸ï¼é£ä¹å¨é»è®¤æ
åµä¸æä»¬ä¼çå° [object Object]ã
è¿éæå°çé»è®¤ç valueOf åªæ¯ä¸ºäºå®æ´èµ·è§ï¼ä»¥é¿å
æ··æ·ãæ£å¦ä½ çå°çï¼å®è¿å对象æ¬èº«ï¼å æ¤è¢«å¿½ç¥ãå«é®æä¸ºä»ä¹ï¼è¿æ¯åå²åå ãæä»¥æä»¬å¯ä»¥åè®¾å®æ ¹æ¬å°±ä¸åå¨ã
让æä»¬å®ç°ä¸ä¸è¿äºæ¹æ³æ¥èªå®ä¹è½¬æ¢ã
ä¾å¦ï¼è¿éç user æ§è¡åå颿å°çé£ä¸ª user 䏿 ·çæä½ï¼ä½¿ç¨ toString å valueOf çç»åï¼è䏿¯ Symbol.toPrimitiveï¼ï¼
let user = {
name: "John",
money: 1000,
// å¯¹äº hint="string"
toString() {
return `{name: "${this.name}"}`;
},
// å¯¹äº hint="number" æ "default"
valueOf() {
return this.money;
}
};
alert(user); // toString -> {name: "John"}
alert(+user); // valueOf -> 1000
alert(user + 500); // valueOf -> 1500
æä»¬å¯ä»¥çå°ï¼æ§è¡çå¨ä½ååé¢ä½¿ç¨ Symbol.toPrimitive çé£ä¸ªä¾åç¸åã
é常æä»¬å¸ææä¸ä¸ªâå
¨è½âçå°æ¹æ¥å¤çææåå§è½¬æ¢ãå¨è¿ç§æ
åµä¸ï¼æä»¬å¯ä»¥åªå®ç° toStringï¼å°±åè¿æ ·ï¼
let user = {
name: "John",
toString() {
return this.name;
}
};
alert(user); // toString -> John
alert(user + 500); // toString -> John500
å¦ææ²¡æ Symbol.toPrimitive å valueOfï¼toString å°å¤çææåå§è½¬æ¢ã
转æ¢å¯ä»¥è¿åä»»ä½åå§ç±»å
å ³äºææåå§è½¬æ¢æ¹æ³ï¼æä¸ä¸ªéè¦çç¹éè¦ç¥éï¼å°±æ¯å®ä»¬ä¸ä¸å®ä¼è¿å âhintâ çåå§å¼ã
没æéå¶ toString() æ¯å¦è¿ååç¬¦ä¸²ï¼æ Symbol.toPrimitive æ¹æ³æ¯å¦ä¸º "number" hint è¿åæ°åã
å¯ä¸å¼ºå¶æ§çäºæ æ¯ï¼è¿äºæ¹æ³å¿ é¡»è¿åä¸ä¸ªåå§å¼ï¼è䏿¯å¯¹è±¡ã
ç±äºåå²åå ï¼å¦æ toString æ valueOf è¿åä¸ä¸ªå¯¹è±¡ï¼åä¸ä¼åºç° errorï¼ä½æ¯è¿ç§å¼ä¼è¢«å¿½ç¥ï¼å°±åè¿ç§æ¹æ³æ ¹æ¬ä¸åå¨ï¼ãè¿æ¯å ä¸ºå¨ JavaScript è¯è¨åå±åæï¼æ²¡æå¾å¥½ç âerrorâ çæ¦å¿µã
ç¸åï¼Symbol.toPrimitive æ´ä¸¥æ ¼ï¼å® å¿
é¡» è¿åä¸ä¸ªåå§å¼ï¼å¦åå°±ä¼åºç° errorã
è¿ä¸æ¥ç转æ¢
æä»¬å·²ç»ç¥éï¼è®¸å¤è¿ç®ç¬¦å彿°æ§è¡ç±»å转æ¢ï¼ä¾å¦ä¹æ³ * 尿使°è½¬æ¢ä¸ºæ°åã
妿æä»¬å°å¯¹è±¡ä½ä¸ºåæ°ä¼ éï¼åä¼åºç°ä¸¤ä¸ªè¿ç®é¶æ®µï¼
- 对象被转æ¢ä¸ºåå§å¼ï¼éè¿å颿们æè¿°çè§åï¼ã
- 妿è¿éè¦è¿ä¸æ¥è®¡ç®ï¼åçæçåå§å¼ä¼è¢«è¿ä¸æ¥è½¬æ¢ã
ä¾å¦ï¼
let obj = {
// toString 卿²¡æå
¶ä»æ¹æ³çæ
åµä¸å¤çææè½¬æ¢
toString() {
return "2";
}
};
alert(obj * 2); // 4ï¼å¯¹è±¡è¢«è½¬æ¢ä¸ºåå§å¼å符串 "2"ï¼ä¹åå®è¢«ä¹æ³è½¬æ¢ä¸ºæ°å 2ã
- 乿³
obj * 2é¦å å°å¯¹è±¡è½¬æ¢ä¸ºåå§å¼ï¼å符串 â2âï¼ã - ä¹å
"2" * 2å为2 * 2ï¼å符串被转æ¢ä¸ºæ°åï¼ã
äºå å æ³å¨åæ ·çæ åµä¸ä¼å°å ¶è¿æ¥æå符串ï¼å ä¸ºå®æ´æ¿ææ¥åå符串ï¼
let obj = {
toString() {
return "2";
}
};
alert(obj + 2); // 22ï¼"2" + 2ï¼è¢«è½¬æ¢ä¸ºåå§å¼å符串 => 级è
æ»ç»
对象å°åå§å¼ç转æ¢ï¼æ¯ç±è®¸å¤ææä»¥åå§å¼ä½ä¸ºå¼çå å»ºå½æ°åè¿ç®ç¬¦èªå¨è°ç¨çã
è¿éæä¸ç§ç±»åï¼hintï¼ï¼
"string"ï¼å¯¹äºalertåå ¶ä»éè¦å符串çæä½ï¼"number"ï¼å¯¹äºæ°å¦è¿ç®ï¼"default"ï¼å°æ°è¿ç®ç¬¦ï¼é常对象以å"number"ç¸åçæ¹å¼å®ç°"default"转æ¢ï¼
è§èæç¡®æè¿°äºåªä¸ªè¿ç®ç¬¦ä½¿ç¨åªä¸ª hintã
转æ¢ç®æ³æ¯ï¼
- è°ç¨
obj[Symbol.toPrimitive](hint)妿è¿ä¸ªæ¹æ³åå¨ï¼ - å¦åï¼å¦æ hint æ¯
"string"- å°è¯è°ç¨
obj.toString()æobj.valueOf()ï¼æ 论åªä¸ªåå¨ã
- å°è¯è°ç¨
- å¦åï¼å¦æ hint æ¯
"number"æè"default"- å°è¯è°ç¨
obj.valueOf()æobj.toString()ï¼æ 论åªä¸ªåå¨ã
- å°è¯è°ç¨
ææè¿äºæ¹æ³é½å¿ é¡»è¿åä¸ä¸ªåå§å¼æè½å·¥ä½ï¼å¦æå·²å®ä¹ï¼ã
å¨å®é
使ç¨ä¸ï¼é常åªå®ç° obj.toString() ä½ä¸ºå符串转æ¢çâå
¨è½âæ¹æ³å°±è¶³å¤äºï¼è¯¥æ¹æ³åºè¯¥è¿å对象çâ人类å¯è¯»â表示ï¼ç¨äºæ¥å¿è®°å½æè°è¯ã
è¯è®º
<code>æ ç¾æå ¥åªæå 个è¯ç代ç ï¼æå ¥å¤è¡ä»£ç å¯ä»¥ä½¿ç¨<pre>æ ç¾ï¼å¯¹äºè¶ è¿ 10 è¡ç代ç ï¼å»ºè®®ä½ ä½¿ç¨æ²ç®±ï¼plnkrï¼JSBinï¼codepenâ¦ï¼