JavaScript 隱式類型轉(zhuǎn)換篇

前言:整理給自己的材原,方便復(fù)習(xí)沸久,不喜勿噴,有錯(cuò)誤歡迎指出余蟹。

一卷胯、隱式轉(zhuǎn)換介紹

隱式轉(zhuǎn)換是指在JavaScript中,當(dāng)運(yùn)算符在運(yùn)算時(shí)威酒,如果兩邊數(shù)據(jù)不統(tǒng)一窑睁,CPU就無(wú)法計(jì)算,這時(shí)我們編譯器會(huì)自動(dòng)將運(yùn)算符兩邊的數(shù)據(jù)做一個(gè)數(shù)據(jù)類型轉(zhuǎn)換葵孤,轉(zhuǎn)成一樣的數(shù)據(jù)類型再計(jì)算担钮。這種無(wú)需程序員手動(dòng)轉(zhuǎn)換,而由編譯器自動(dòng)轉(zhuǎn)換的方式就稱為隱式轉(zhuǎn)換尤仍。

1 > "0" 這行代碼在js中并不會(huì)報(bào)錯(cuò)箫津,編譯器在運(yùn)算符時(shí)會(huì)先把右邊的"0"轉(zhuǎn)成數(shù)字 0 然后在比較大小

二、隱式轉(zhuǎn)換規(guī)則

犀牛書上有關(guān)隱式類型轉(zhuǎn)換的表
轉(zhuǎn)為String類型: +(字符串連接符)
轉(zhuǎn)為Number類型:++ / --  (自增自減運(yùn)算符) +  -  *  /  %(算術(shù)運(yùn)算符) >  <  >=  <=  ==  !=  ===  !==  (關(guān)系運(yùn)算符)
轉(zhuǎn)為Boolean類型:宰啦!(邏輯非運(yùn)算符)
轉(zhuǎn)為布爾類型成為false的有:undefined苏遥、null、空字符串赡模、0田炭、-0、NaN
new Number() 和 Number() 是不同的漓柑,new Number() 創(chuàng)建了一個(gè)Number對(duì)象教硫,Number() 將傳入的參數(shù)轉(zhuǎn)換為數(shù)值字面量
1 + "true"  // "1true"  若+兩邊存在一個(gè)字符串,將另一個(gè)也轉(zhuǎn)為字符串進(jìn)行字符串拼接  String(1) + "true" = "1true"
1 + true  // 2  這里的 + 是算術(shù)運(yùn)算符 1 + Number(true) = 1 + 1 = 2
1 + undefined  // NaN  這里的 + 是算術(shù)運(yùn)算符 1 + Number(undefined) = 1 + NaN = NaN
1 + null  // 1  這里的 + 是算術(shù)運(yùn)算符 1 + Number(null) = 1 + 0 = 1
PS:不要混淆字符串連接符與算術(shù)運(yùn)算符隱式轉(zhuǎn)換規(guī)則

再來(lái)看幾個(gè)例子

“2” > 10  // false  Number(2) > 10 = 2 > 10 = false
"2" > "10"  // true  當(dāng)兩邊都是字符串的時(shí)候欺缘,此時(shí)轉(zhuǎn)為number然后比較關(guān)系栋豫,注意這里并不是按照Number()的形式轉(zhuǎn)為數(shù)字挤安,而是按照字符串對(duì)應(yīng)的unicode編碼來(lái)轉(zhuǎn)成數(shù)字谚殊,charCodeAt(index)  index為字符下標(biāo),默認(rèn)為0蛤铜。
"2".charCodeAt(0) > '10'.charCodeAt(0) = 50 > 49 = true
"abc" > "b"  // false  多個(gè)字符的時(shí)候從左往右依次比較 'a'.charCodeAt(0) = 97  'b'.charCodeAt(0) = 98
"abc" > "aad"  // true 
NaN == NaN  // false 
特殊情況:如果數(shù)據(jù)類型是undefined或null 得出固定結(jié)果
undefined == undefined  // true
undefined == null  // true
null == null  // true
NaN == NaN  // false

三嫩絮、對(duì)象的類型轉(zhuǎn)換

1、對(duì)象到字符串的轉(zhuǎn)換( 這里說(shuō)的是String()方法的原理 )

若具有toString()方法围肥,調(diào)用toString()剿干,如果它返回一個(gè)原始值,將這個(gè)原始值轉(zhuǎn)換為字符串返回
若無(wú)toString()方法穆刻,或toString()的返回值并不是一個(gè)原始值置尔,尋找其valueOf()方法,若存在這個(gè)方法氢伟,調(diào)用它榜轿,如果它返回一個(gè)原始值幽歼,將這個(gè)原始值轉(zhuǎn)換為字符串返回
否則(無(wú)valueOf()valueOf()的返回值不是原始值),JS無(wú)法從toString()或valueOf()方法獲得一個(gè)原始值谬盐。因此甸私,throw TypeError

2、對(duì)象到數(shù)字的轉(zhuǎn)換(這里說(shuō)的是Number()方法的原理)

若具有valueOf()方法飞傀,調(diào)用valueOf()皇型,如果它返回一個(gè)原始值,將這個(gè)原始值轉(zhuǎn)換為數(shù)字返回
若無(wú)valueOf()方法砸烦,或valueOf()的返回值并不是一個(gè)原始值弃鸦,尋找其toString()方法,若存在這個(gè)方法外冀,調(diào)用它寡键,如果它返回一個(gè)原始值,將這個(gè)原始值轉(zhuǎn)換為數(shù)字返回
否則(無(wú)toString()toString()的返回值不是原始值)雪隧,JS無(wú)法從toString()或valueOf()方法獲得一個(gè)原始值西轩,因此,throw TypeError

對(duì)象到數(shù)字的轉(zhuǎn)換和對(duì)象到字符串的轉(zhuǎn)換類似脑沿,只是兩個(gè)方法的調(diào)用順序不同
3藕畔、對(duì)象到布爾值的轉(zhuǎn)換

對(duì)象類型轉(zhuǎn)換為布爾值:均為true,不管其toString()庄拇、valueOf()方法返回什么

數(shù)組類型的轉(zhuǎn)換實(shí)際上也遵循以上三條注服,不過(guò)它覆蓋了原型鏈上的toString()方法,改為返回`數(shù)組的join()`方法的返回結(jié)果
4措近、各類型的toString()溶弟、valueOf()方法的返回值

對(duì)象(Object)
toString()返回: “[object Object]”
valueOf()返回: 對(duì)象本身

var a = { b: 1 }
a.toString() ?  "[object Object]"
a.valueOf() ?  {b: 1}

數(shù)組(Array)
toString()返回: this.join()的返回值
valueOf()返回: 數(shù)組本身

var a = [1,2,3]
a.toString() ? "1,2,3"
a.valueOf() ?  [1, 2, 3]

方法(Function)
toString()返回: 整個(gè)函數(shù)字符串
valueOf()返回: 方法本身

var a = function () { b =333; return 111; }
a.toString()  ?  "function(){b =333; return 111;}"
a.valueOf()  ? ? () { b =333; return 111; }

日期(Date)
toString()返回:完整事件字符串
valueOf()返回:從1970年1月1日0時(shí)0分0秒(UTC,即協(xié)調(diào)世界時(shí))到該日期的毫秒數(shù)瞭郑。

var a = new Date()
a.toString() ? "Thu Mar 07 2019 13:48:31 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)"
a.valueOf() ? 1551937711874

Error
toString()返回:"Error {錯(cuò)誤描述}"
valueOf()返回:錯(cuò)誤本身

正則(RegExp)
toString()返回:正則式完整字符串
valueOf()返回:正則本身

var a = new RegExp('^ass[^f]\w?','gi')
a.toString() ? "/^ass[^f]\w?/gi"
a.valueOf() ?  /^ass[^f]\w?/gi“

四辜御、總結(jié)和實(shí)踐!

1、 算術(shù)運(yùn)算符(+屈张、-擒权、*、/阁谆、++碳抄、–、%…)

'+'作為一個(gè)雙目運(yùn)算符: 若+兩邊存在一個(gè)字符串场绿,將另一個(gè)也轉(zhuǎn)為字符串進(jìn)行字符串拼接剖效。
其他情況下,不管雙目還是單目,都轉(zhuǎn)為數(shù)值類型

2璧尸、關(guān)系運(yùn)算符(>劝贸、<、==逗宁、!=…)

===映九、!==:同時(shí)對(duì)比類型和值,兩個(gè)都為真才返回真
==瞎颗、!=: 若兩邊均為對(duì)象件甥,對(duì)比它們的引用是否相同
!(邏輯非): 將其后變量或表達(dá)式轉(zhuǎn)為布爾值
對(duì)比字符串:從頭至尾掃描逐個(gè)比較每個(gè)字符的unicode碼,直到分出大小
其他情況下哼拔,兩邊均轉(zhuǎn)為數(shù)值類型

NaN與任何值都不相同引有,與任何值比較都返回false
對(duì)象類型在運(yùn)算時(shí)進(jìn)行類型轉(zhuǎn)換都先調(diào)用valueOf()方法,再嘗試toString()方法
在進(jìn)行對(duì)象字面量(這里說(shuō)的是JSON格式的對(duì)象字面量)運(yùn)算時(shí)要注意倦逐,若運(yùn)算符兩邊都是字面量譬正,
則將它們都視為對(duì)象字面量進(jìn)行類型轉(zhuǎn)換;
若只有一個(gè)字面量時(shí)要注意檬姥,當(dāng)這個(gè)字面量在首位時(shí)曾我,會(huì)被當(dāng)做一個(gè)塊看待。
{} + {}  =>  "[object Object][object Object]"
{}被當(dāng)做一個(gè)塊健民,相當(dāng)于執(zhí)行 ( {}, +[] )抒巢,計(jì)算的是+[]的結(jié)果
{} + []  => 0   
{ a: 1 } + []  => 0
{} == []  =>  報(bào)錯(cuò)  ({}, ==[])  =>  報(bào)錯(cuò)
變量形式運(yùn)算正常
var a = { q:1 }
a + []  =>  "[object Object]"
[] + a  =>  "[object Object]"
[1,2,3] + []  =>  "1,2,3" + ""  =>  "1,2,3"
[] + {}  =>  "" + "[object Object]"  =>  "[object Object]"
[] == 0  // true      []  =>  ""  =>  0
![] == 0  // true    ![] => false => 0
[] == ![]  // true      []  =>  ""  =>  0    ![] => false => 0
[] == []  // false  比較引用地址
{} == {}  // false  比較引用地址
{} == !{}  //  false    !{}  => false => 0    {} =>  "[object Object]" => Number("[object Object]")  =>  NaN

如果你想了解更多,可以閱讀原文JavaScript類型轉(zhuǎn)換原理性的問(wèn)題 或者譯文JavaScript類型轉(zhuǎn)換原理性的問(wèn)題

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末秉犹,一起剝皮案震驚了整個(gè)濱河市蛉谜,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌崇堵,老刑警劉巖型诚,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異鸳劳,居然都是意外死亡狰贯,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門棍辕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)暮现,“玉大人还绘,你說(shuō)我怎么就攤上這事楚昭。” “怎么了拍顷?”我有些...
    開(kāi)封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵抚太,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我,道長(zhǎng)尿贫,這世上最難降的妖魔是什么电媳? 我笑而不...
    開(kāi)封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮庆亡,結(jié)果婚禮上匾乓,老公的妹妹穿的比我還像新娘。我一直安慰自己又谋,他們只是感情好拼缝,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著彰亥,像睡著了一般咧七。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上任斋,一...
    開(kāi)封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天继阻,我揣著相機(jī)與錄音,去河邊找鬼废酷。 笑死瘟檩,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的澈蟆。 我是一名探鬼主播芒帕,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼丰介!你這毒婦竟也來(lái)了背蟆?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤哮幢,失蹤者是張志新(化名)和其女友劉穎带膀,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體橙垢,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡垛叨,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了柜某。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嗽元。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖喂击,靈堂內(nèi)的尸體忽然破棺而出剂癌,到底是詐尸還是另有隱情,我是刑警寧澤翰绊,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布佩谷,位于F島的核電站旁壮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏谐檀。R本人自食惡果不足惜抡谐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望桐猬。 院中可真熱鬧麦撵,春花似錦、人聲如沸溃肪。這莊子的主人今日做“春日...
    開(kāi)封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)乍惊。三九已至杜秸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間润绎,已是汗流浹背撬碟。 一陣腳步聲響...
    開(kāi)封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留莉撇,地道東北人呢蛤。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像棍郎,于是被迫代替她去往敵國(guó)和親其障。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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