【重學(xué)前端學(xué)習(xí)筆記】關(guān)于類型,有哪些你不知道的細(xì)節(jié)

在學(xué)習(xí)《關(guān)于類型,有哪些你不知道的細(xì)節(jié)》一章節(jié)中非驮,講到了javascript內(nèi)置了Symbol.toPrimitive屬性,可自定義類型轉(zhuǎn)換操作必怜。

typeof

我們最常使用typeof來進(jìn)行類型檢測(cè)养涮,對(duì)于基本類型使用typeof能得到我們想要的結(jié)果

console.log(typeof '123')               //'string'
console.log(typeof 123)                 //'number'
console.log(typeof undefined)           //'undefined'
console.log(typeof true)                //'boolean'
console.log(typeof Symbol('foo'))       //'symbol'

對(duì)于復(fù)雜類型使用typeof進(jìn)行判斷,就不是我們想要的結(jié)果了罐监。

console.log(typeof {a: 1})                  //'object'
console.log(typeof new Date())              //'object'
console.log(typeof [1,3,4])                 //'object'
console.log(typeof new String('123'))       //'object'
console.log(typeof new RegExp())            //'object'

顯然我們對(duì)new Date()進(jìn)行類型判斷時(shí)吴藻,想要得到是Date;對(duì)數(shù)組進(jìn)行類型判斷時(shí)弓柱,想要得到Array沟堡,但是用typeof進(jìn)行判斷時(shí),得到的結(jié)果都是object矢空,所以對(duì)復(fù)雜類型使用typeof結(jié)果都是object航罗。

這里有兩個(gè)特殊的值,對(duì)他們使用typeof進(jìn)行類型檢測(cè)屁药,和你想象的結(jié)果會(huì)不一樣

console.log(typeof null)                //'object'
console.log(typeof function fn(){})     //'function'

雖然null是基本類型粥血,使用typeof進(jìn)行類型檢測(cè)時(shí),結(jié)果卻是object酿箭;而function是復(fù)雜類型复亏,使用typeof進(jìn)行類型檢測(cè)卻是function

當(dāng)你類型不確定時(shí)缭嫡,要謹(jǐn)慎使用typeof進(jìn)行類型檢測(cè)缔御。

toString

使用typeof無法準(zhǔn)確的判斷出想要的類型,這里就可以使用toString方法進(jìn)行判斷

let type = {}.toString
console.log(type.call('123'))                   //'[object String]'
console.log(type.call(123))                     //'[object Number]'
console.log(type.call(true))                    //'[object Boolean]'
console.log(type.call(undefined))               //'[object Undefined]'
console.log(type.call(Symbol('foo')))           //'[object Symbol]'
console.log(type.call(null))                    //'[object Null]'
console.log(type.call(function fn() {}))        //'[object Function]'
console.log(type.call({a: 11}))                 //'[object Object]'
console.log(type.call(new Date))                //'[object Date]'
console.log(type.call(new RegExp))              //'[object RegExp]'
console.log(type.call([1,2,3]))                 //'[object Array]'

使用toString可以很好的解決了類型判斷的問題妇蛀,從上面例子中可以看出無論是基本類型耕突,還是復(fù)雜類型都能準(zhǔn)確的判斷出來。

這里({}.toString).call(123)等同于Object.prototype.toString.call(123)

Symbol.toPrimitive

前面講解了如何進(jìn)行類型檢測(cè)评架,在類型檢測(cè)時(shí)眷茁,實(shí)際上是發(fā)生了類型轉(zhuǎn)換,那么類型轉(zhuǎn)換在javascript內(nèi)部是如何實(shí)現(xiàn)的呢纵诞?

將對(duì)象轉(zhuǎn)換到基本類型時(shí)上祈,javascript提供了toSringvalueOf的轉(zhuǎn)換方法。

let o = {
    valueOf: () => {console.log('valueOf'); },
    toString: () => {console.log('toString');}
}
String(o)       //'toString'
Number(o)       //'valueOf'

將對(duì)象轉(zhuǎn)換成string類型時(shí),會(huì)調(diào)用toString方法雇逞;將對(duì)象轉(zhuǎn)換成number時(shí)荤懂,會(huì)調(diào)用valueOf方法。

如果在調(diào)用toString時(shí)沒有得到基本類型值時(shí)塘砸,則會(huì)調(diào)用valueOf节仿,再調(diào)用valueOf時(shí)也沒有得到基本類型,則會(huì)報(bào)TypeError錯(cuò)誤

同理在調(diào)用valueOf時(shí)也是如此掉蔬。

那么為什么在轉(zhuǎn)換成string時(shí)會(huì)先調(diào)用toString方法廊宪,而轉(zhuǎn)換成number時(shí)會(huì)先調(diào)用valueOf方法呢?

這是因?yàn)?code>javascript內(nèi)置了一個(gè)Symbol.toPrimitive的屬性女轿。當(dāng)對(duì)象被要被轉(zhuǎn)換為基本類型時(shí)箭启,會(huì)調(diào)用Symbol.toPrimitive,同時(shí)會(huì)傳入一個(gè)hint參數(shù):

  • 如果想要轉(zhuǎn)換成string蛉迹,hint值為string傅寡,則會(huì)順序調(diào)用toStringvalueOf北救,toString一定會(huì)被執(zhí)行荐操,其值如果返回基本類型時(shí),則return珍策,終止運(yùn)算托启,否則繼續(xù)調(diào)用valueOf,如果過調(diào)用valueOf沒有得到基本類型攘宙,則會(huì)報(bào)TypeError錯(cuò)誤屯耸;
  • 如果想要轉(zhuǎn)換成numberhint值為number蹭劈,則會(huì)順序調(diào)用valueOf疗绣、toStringvalueOf一定會(huì)被執(zhí)行链方,其值如果返回基本類型時(shí)持痰,則return灶搜,終止運(yùn)算祟蚀,否則繼續(xù)調(diào)用toString方法,如果調(diào)用toString沒有得到基本類型割卖,則會(huì)報(bào)TypeError錯(cuò)誤前酿;
  • 如果不確定是到底要轉(zhuǎn)換成string還是numberhint值為default鹏溯,則會(huì)順序調(diào)用valueOf罢维、toStringvalueOf一定會(huì)被執(zhí)行丙挽,其值如果返回基本類型時(shí)肺孵,則return匀借,終止運(yùn)算,否則繼續(xù)調(diào)用toString方法平窘,如果調(diào)用toString沒有得到基本類型吓肋,則會(huì)報(bào)TypeError錯(cuò)誤。

如何用戶顯示指定了Symbol.toPrimitive方法瑰艘,這會(huì)直接調(diào)用用戶定義的Symbol.toPrimitive方法:

let o = {
    [Symbol.toPrimitive](hint){
        console.log(`hint: ${hint}`)
    },
    valueOf: () => {console.log('valueOf'); },      //未執(zhí)行
    toString: () => {console.log('toString');}      //未執(zhí)行
}
String(o)       //'hint: string'
Number(o)       //'hint: number'
o + ''          //'hint: default'
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末是鬼,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子紫新,更是在濱河造成了極大的恐慌均蜜,老刑警劉巖,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件芒率,死亡現(xiàn)場(chǎng)離奇詭異囤耳,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)偶芍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門紫皇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人腋寨,你說我怎么就攤上這事聪铺。” “怎么了萄窜?”我有些...
    開封第一講書人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵铃剔,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我查刻,道長(zhǎng)键兜,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任穗泵,我火速辦了婚禮普气,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘佃延。我一直安慰自己现诀,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開白布履肃。 她就那樣靜靜地躺著仔沿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪尺棋。 梳的紋絲不亂的頭發(fā)上封锉,一...
    開封第一講書人閱讀 49,166評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼成福。 笑死碾局,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的奴艾。 我是一名探鬼主播擦俐,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼握侧!你這毒婦竟也來了蚯瞧?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬榮一對(duì)情侶失蹤品擎,失蹤者是張志新(化名)和其女友劉穎埋合,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體萄传,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡甚颂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了秀菱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片振诬。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖衍菱,靈堂內(nèi)的尸體忽然破棺而出赶么,到底是詐尸還是另有隱情,我是刑警寧澤脊串,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布辫呻,位于F島的核電站,受9級(jí)特大地震影響琼锋,放射性物質(zhì)發(fā)生泄漏放闺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一缕坎、第九天 我趴在偏房一處隱蔽的房頂上張望怖侦。 院中可真熱鬧,春花似錦谜叹、人聲如沸匾寝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旗吁。三九已至,卻和暖如春停局,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來泰國打工董栽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留码倦,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓锭碳,卻偏偏與公主長(zhǎng)得像袁稽,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子擒抛,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容