【JS】隱式類型轉(zhuǎn)換

1. 前置知識(shí)

顯式類型轉(zhuǎn)換

2. - * / %運(yùn)算符

Number類型直接進(jìn)行數(shù)學(xué)運(yùn)算,非Number類型,轉(zhuǎn)換成Number類型后刻盐,進(jìn)行數(shù)學(xué)運(yùn)算

3. + 運(yùn)算符

3.1 作為一元運(yùn)算符

表示對(duì)對(duì)象進(jìn)行Number()轉(zhuǎn)換

console.log(+{});//NaN
console.log(+["Lawson", "Nion"]);//NaN
console.log(+[]);//0
console.log(+false);//0
console.log(+"123");//123
console.log(+null);//0
console.log(+undefined);//NaN

3.2 作為二目運(yùn)算符

+號(hào)左右兩邊有一個(gè)有優(yōu)先級(jí)高的噪珊,就往這個(gè)類型轉(zhuǎn)

  • 優(yōu)先級(jí)順序:String > Number > Boolean == null == undefined
  • Object特殊處理降传,得到基本類型后再進(jìn)行優(yōu)先級(jí)判定
    • 若有valueOf()方法舶治,則先調(diào)用琼讽,若得到基本類型熔萧,則使用
    • 若沒有valueOf()方法或者valueOf()方法返回不是基本類型糖驴,則嘗試調(diào)用toString()方法
    • 若有toString()方法,則調(diào)用佛致,若得到基本類型贮缕,則使用
    • 若沒有toString方法,或者toString得到的不是基本類型俺榆,則報(bào)錯(cuò)
  1. 從左至右進(jìn)行分割運(yùn)算
  2. 優(yōu)先級(jí)低的向優(yōu)先級(jí)高的類型進(jìn)行轉(zhuǎn)換
  3. 如果轉(zhuǎn)換后兩邊都不是String或者Number感昼,則往Number轉(zhuǎn)
let obj = {
  name: "Lawson",
  toString() {
    console.log("called toString");
    return false;
  },
  valueOf() {
    console.log("called valueOf");
    return [];
  },
};

console.log(1 === 1 + obj);
//called valueOf
//called toString
//true

//先得到了false,Boolean和Number罐脊,Number優(yōu)先級(jí)高抑诸,往Number轉(zhuǎn)換
//1 + false => 1 + 0 => 1
let obj = {
  name: "Lawson",
  toString() {
    console.log("called toString");
    return 1;
  },
  valueOf() {
    console.log("called valueOf");
    return [];
  },
};

console.log(true + obj);
//called valueOf
//called toString
//2

//先得到了1烂琴,Boolean和Number,Number優(yōu)先級(jí)高蜕乡,往Number轉(zhuǎn)換
//true + 1 => 1 + 1 => 2
console.log(true + false);//1
console.log(true + null);//1
console.log(null + undefined);//NaN
console.log(true + undefined);//NaN
//[]調(diào)用valuteOf會(huì)得到""奸绷,是String,所以都往String轉(zhuǎn)
console.log(null + []);//'null'
//{}被識(shí)別為對(duì)象层玲,并通過toString()轉(zhuǎn)換成'[object Object]'
console.log(1 + {});//"1[object Object]"
//{}會(huì)被識(shí)別為代碼塊
console.log({} + 1);//1
//1 + false => 1 + 0 => 1
//1 + '2' => '1' + '2' => '12'
//'12' + null => '12' + 'null' => '12null'
console.log(1 + false + '2' + null);//'12null'

//1 + false => 1 + 0 => 1
//1+ null => 1 + 0 => 1
//1 + '2' => '1' + '2' => '12'
console.log(1 + false + null + '2');//'12'

//false + null => 0 + 0 => 0
//0 + 1 => 1
//1 + '2' => '1' + '2' => '12'
console.log(false + null + 1 + '2');//'12'

//false + null => 0 + 0 => 0
//0 + '2' => '0' + '2' => '02'
//'02' + 1 => '02' + '1' => '021'
console.log(false + null + '2' + 1);//'021'

4. > >= < <=邏輯運(yùn)算

Number類型直接進(jìn)行邏輯運(yùn)算号醉,非Number類型,轉(zhuǎn)換成Number類型后辛块,進(jìn)行邏輯運(yùn)算

5. ==邏輯運(yùn)算

5.1 類型相同畔派,直接比較

  • NaNNaN不等
NaN == NaN //false
  • Object類型比較堆地址
{} == {} //false
[] == [] //false
[] == {} //false 不進(jìn)行類型轉(zhuǎn)換
//!Boolean([]) == !Boolean({}) => !true == !true => false == false
![] == !{} //true
//[] == !Boolean([]) => [] == !true => Number([]) == Number(false) => 0 == 0
[] == ![] //true

var a = b = {};
a == b //true
  • +0-0润绵、0相等
  • 其他都相等

5.2 類型不同线椰,先轉(zhuǎn)換

  1. nullundefined相等
null == undefined //true
  1. ObjectDate類型轉(zhuǎn)為String類型)、Number尘盼、String憨愉、Boolean之間的比較都是返回轉(zhuǎn)換為Number類型進(jìn)行比較
//Number(123) == Number('123')
123 == '123' //true
//Number(0) == Number(false)
0 == false //true
//Number(0) == Number([]) => 0 == Number('') => 0 == 0
0 == [] //true
//Number(0) == Number({}) => 0 == Number('[object Object]') => 0 == NaN
0 == {} //false
//Number([]) == Number({}) => Number('') == Number('[object Object]') => 0 == NaN

new Date('2020/11/28').valueOf() //1606492800000
new Date('2020/11/28').toString() //"Sat Nov 28 2020 00:00:00 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)"
new Date('2020/11/28') == "Sat Nov 28 2020 00:00:00 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)" //true
new Date('2020/11/28') == 1606492800000 //false
  1. 其他類型進(jìn)行轉(zhuǎn)換時(shí)都不相等(null和undefined與其他類型都不相等)
null == 0 //false
undefined == {} //false

6. && || 邏輯運(yùn)算

6.1 &&

  • 從左往右執(zhí)行代碼塊
  • 執(zhí)行代碼塊A,得出結(jié)果resA
  • Boolean(resA)為false卿捎,則返回resA配紫,不執(zhí)行代碼塊B
  • Boolean(resA)為true,則繼續(xù)執(zhí)行代碼塊B午阵,得出結(jié)果resB
  • Boolean(resB)為false躺孝,則返回resB,不執(zhí)行代碼塊C
  • Boolean(resB)為true底桂,則繼續(xù)執(zhí)行代碼塊C植袍,得出結(jié)果resC
  • 依次遞進(jìn),直到Boolean(resN)為false籽懦,或者執(zhí)行完所有
function A(){
  console.log('called A.');
  return [] == ![];
}
function B(){
  console.log('called B.');
  return undefined + 0;
}
function C(){
  console.log('called C.');
  return true;
}

console.log(A() && B() && C());//NaN
//called A. 
//called B.
//NaN

//A執(zhí)行奋单,結(jié)果為[] == ![],通過Boolean([] == ![]) => true猫十,會(huì)執(zhí)行一個(gè)表達(dá)式
//B執(zhí)行览濒,結(jié)果為undefined + 0,通過Boolean(undefined + 0) => false拖云,會(huì)停止向下執(zhí)行贷笛,返回undefined + 0的表達(dá)式結(jié)果undefined + 0 => Number(undefined) + 0 => NaN + 0 => NaN
//C不會(huì)執(zhí)行

6.2 ||

  • 每一步的返回值進(jìn)行Boolean操作
  • 返回第一個(gè)可轉(zhuǎn)換為true的表達(dá)式
  • 可轉(zhuǎn)換為true的表達(dá)式后面的表達(dá)式會(huì)被【短路】(不會(huì)執(zhí)行)
function A() {
  console.log("called A.");
  return [] == [];
}
function B() {
  console.log("called B.");
  return null + 1;
}
function C() {
  console.log("called C.");
  return true;
}

console.log(A() || B() || C());
//called A. 
//called B.
//1

//A執(zhí)行,return結(jié)果為[] == []宙项,類型相同乏苦,直接比較堆地址,不等,計(jì)算結(jié)果為false汇荐,繼續(xù)向右執(zhí)行
//B執(zhí)行洞就,結(jié)果為null + 1,通過Boolean(null + 1) => true掀淘,會(huì)停止向下執(zhí)行旬蟋,返回null + 1的表達(dá)式結(jié)果null + 1 => Number(null) + 1 => 0 + 1 => 1
//C不會(huì)執(zhí)行
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市革娄,隨后出現(xiàn)的幾起案子倾贰,更是在濱河造成了極大的恐慌,老刑警劉巖拦惋,帶你破解...
    沈念sama閱讀 212,080評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件匆浙,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡厕妖,警方通過查閱死者的電腦和手機(jī)首尼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,422評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)言秸,“玉大人软能,你說(shuō)我怎么就攤上這事【觯” “怎么了?”我有些...
    開封第一講書人閱讀 157,630評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵破加,是天一觀的道長(zhǎng)俱恶。 經(jīng)常有香客問我,道長(zhǎng)范舀,這世上最難降的妖魔是什么合是? 我笑而不...
    開封第一講書人閱讀 56,554評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮锭环,結(jié)果婚禮上聪全,老公的妹妹穿的比我還像新娘。我一直安慰自己辅辩,他們只是感情好难礼,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,662評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著玫锋,像睡著了一般蛾茉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上撩鹿,一...
    開封第一講書人閱讀 49,856評(píng)論 1 290
  • 那天谦炬,我揣著相機(jī)與錄音,去河邊找鬼。 笑死键思,一個(gè)胖子當(dāng)著我的面吹牛础爬,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吼鳞,決...
    沈念sama閱讀 39,014評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼看蚜,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了赖条?” 一聲冷哼從身側(cè)響起失乾,我...
    開封第一講書人閱讀 37,752評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎纬乍,沒想到半個(gè)月后碱茁,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,212評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡仿贬,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,541評(píng)論 2 327
  • 正文 我和宋清朗相戀三年纽竣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片茧泪。...
    茶點(diǎn)故事閱讀 38,687評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蜓氨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出队伟,到底是詐尸還是另有隱情穴吹,我是刑警寧澤,帶...
    沈念sama閱讀 34,347評(píng)論 4 331
  • 正文 年R本政府宣布嗜侮,位于F島的核電站港令,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏锈颗。R本人自食惡果不足惜顷霹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,973評(píng)論 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望击吱。 院中可真熱鬧淋淀,春花似錦、人聲如沸覆醇。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,777評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至憨奸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背似芝。 一陣腳步聲響...
    開封第一講書人閱讀 32,006評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工那婉, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人详炬。 一個(gè)月前我還...
    沈念sama閱讀 46,406評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像呛谜,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子枪萄,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,576評(píng)論 2 349

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