js隱式轉(zhuǎn)換

先看個例子

const a = {
  i: 1,
  toString: function () {
    return a.i++;
  }
}
if(a==1){
  console.log('1')
}
if(a==2){
  console.log('2')
}
if(a==3){
  console.log('3')
}

答案自己運算試試

先說說js數(shù)據(jù)類型

  1. 基礎(chǔ)類型(原始值):
    Undefined究恤、Null承桥、String雷滋、Number类缤、Boolean臼勉、Symbol
  2. 復(fù)雜類型(對象值):
    Object

三種隱式轉(zhuǎn)換類型

涉及隱式轉(zhuǎn)換最多的兩個運算符 + 和 ==
+運算符即可數(shù)字相加,也可以字符串相加餐弱。
-*/ 這些運算符只會針對number類型宴霸,估轉(zhuǎn)換的結(jié)果只能是轉(zhuǎn)換成number類型。

隱式轉(zhuǎn)換中主要涉及到三種轉(zhuǎn)換:

  1. 將值轉(zhuǎn)為原始值(基礎(chǔ)類型的值)膏蚓,ToPrimitive()
  2. 將值轉(zhuǎn)為數(shù)字瓢谢,ToNumber()
  3. 將值轉(zhuǎn)為字符串,ToString()

通過ToPrimitive將值轉(zhuǎn)換為原始值

ToPrimitive(input,PreferredType?)
input是要轉(zhuǎn)換的值驮瞧,PreferredType是可選參數(shù)氓扛,可以是Number或String類型。他只是一個轉(zhuǎn)換標志,轉(zhuǎn)化后的結(jié)果并不一定是這個參數(shù)所指的類型采郎,但是轉(zhuǎn)換結(jié)果一定是一個原始值或者報錯千所。

  • 如果PreferredType被編輯為Number,則會進行下面的操作流程來轉(zhuǎn)換輸入的值蒜埋。
1. 如果輸入的值已經(jīng)是一個原始值淫痰,則直接返回它。
2. 否則整份,如果輸入的值是一個對象待错,則調(diào)用該對象的valueOf()方法,如果valueOf()方法的返回值是一個原始值烈评,則返回這個原始值火俄。
3. 否則,調(diào)用這個對象的toString()方法讲冠,如果toString()方法返回的是一個原始值瓜客,則返回這個原始值。
4. 否則沟启,拋出TypeError異常忆家。
  • 如果PreferredType被標記為String,則會進行下面的操作流程來轉(zhuǎn)換輸入的值德迹。
1. 如果輸入的值已經(jīng)是一個原始值芽卿,則直接返回它。
2. 否則胳搞,調(diào)用這個對象的toString()方法卸例,如果toString()方法返回的是一個原始值,則返回這個原始值肌毅。
3. 否則筷转,如果輸入的值是一個對象,則調(diào)用該對象的valueOf()方法悬而,如果valueOf()方法的返回值是一個原始值呜舒,則返回這個原始值。
4. 否則笨奠,拋出TypeError異常袭蝗。

既然PreferredType是可選參數(shù),那么如果沒有這個參數(shù)時般婆,怎么轉(zhuǎn)換到腥?規(guī)則如下:

1. 該對象為Date類型,則PreferredType被設(shè)置為String
2. 否則蔚袍,PreferredType被設(shè)置為Number

valueOf方法和toString方法解析

Object.prototype具有valueOf和toString方法乡范,而Object.prototype是所有對象原型鏈頂層原型,所有對象都會繼承該原型的方法,故任何對象都會有valueOf和toString方法晋辆。

valueOf函數(shù)對js的常見內(nèi)置對象轉(zhuǎn)換結(jié)果:

  1. Number渠脉、Boolean、String這三種構(gòu)造函數(shù)生成的基礎(chǔ)值的對象形式栈拖,通過valueOf轉(zhuǎn)換后變成相應(yīng)的原始值连舍。
var num = new Number('123');
num.valueOf();  //123

var str = new String('123');
str.valueOf(); //'123'

var bool = new Boolean('fa');
bool.valueOf(); // true
  1. Date這種特殊的對象,其原型Date.prototype上內(nèi)置的vauleOf函數(shù)將日期轉(zhuǎn)換為毫秒的形式的數(shù)值涩哟。
var a = new Date();
a.valueOf();  //1608262149351
  1. 除此之外返回的都為this,即對象本身:
var a = new Array();
a.valueOf()  //[]

var b = new Object({});
b.valueOf()  //{}

toString函數(shù)對js的常見內(nèi)置對象轉(zhuǎn)換結(jié)果:

var num = new Number('123sd');  //若為純數(shù)字盼玄,則為數(shù)字字符串
num.toString(); //'NaN'

var str = new String('12df')
str.toString();  //12df

var bool = new Boolean('fd');
bool.toString(); // 'true'

var arr = new Array(1,2);
arr.toString();  //'1,2'

var d = new Date();
d.toString();   //"Fri Dec 18 2020 11:52:17 GMT+0800 (中國標準時間)"

var func = function(){}
func.toString();  // 'function(){}'

var obj = new Object({});
obj.toString(); // "[object Object]"

練習題

({} + {} ) = ?
兩個對象的值進行+運算符贴彼,肯定要先進行隱式轉(zhuǎn)換為原始類型才能進行計算。
1. 進行ToPrimitive轉(zhuǎn)換埃儿,由于沒有指定PeferredType類型器仗,{}會使默認值為Number,進行ToPrimitive(input,Number)運算童番。
2. 所以會執(zhí)行vauleOf方法精钮,({}).valueOf(),返回的還是{}對象,不是原始值剃斧。
3. 繼續(xù)執(zhí)行toString方法轨香,({}).toString(),返回"[object Object]",是原始值。
所以答案是"[object Object]" + "[object Object]" = "[object Object][object Object]"
2 * {} = ?
1幼东、首先*運算符只能對number類型進行運算臂容,故第一步就是對{}進行ToNumber類型轉(zhuǎn)換。
2根蟹、由于{}是對象類型脓杉,故先進行原始類型轉(zhuǎn)換,ToPrimitive(input, Number)運算简逮。
3球散、所以會執(zhí)行valueOf方法,({}).valueOf(),返回的還是{}對象散庶,不是原始值蕉堰。
4、繼續(xù)執(zhí)行toString方法督赤,({}).toString(),返回"[object Object]"嘁灯,是原始值。
5躲舌、轉(zhuǎn)換為原始值后再進行ToNumber運算丑婿,"[object Object]"就轉(zhuǎn)換為NaN。
故最終的結(jié)果為 2 * NaN = NaN
  1 + false
  1 + '2' + false
  1 + '2' - false
  1 - '2' + false
  1 - '2' - false
const a = {
  i: 1,
  toString: function () {
    return a.i++;
  }
}
if(a==1){
  console.log('1')
}
if(a==2){
  console.log('2')
}
if(a==3){
  console.log('3')
}

解析:

1. 當執(zhí)行a == 1 && a == 2 && a == 3 時,會從左到右一步一步解析羹奉,首先 a ==  1秒旋,會進行上面第9步轉(zhuǎn)換。ToPrimitive(a诀拭, Number) == 1迁筛。
2. ToPrimitive(a, Number),按照上面原始類型轉(zhuǎn)換規(guī)則耕挨,會先調(diào)用valueOf方法细卧,a的valueOf方法繼承自O(shè)bject.prototype。返回a本身筒占,而非原始類型贪庙,故會調(diào)用toString方法。
3. 因為toString被重寫翰苫,所以會調(diào)用重寫的toString方法止邮,故返回1,注意這里是i++奏窑,而不是++i导披,它會先返回i,在將i+1埃唯。故ToPrimitive(a, Number) = 1撩匕。也就是1 == 1,此時i = 1 + 1 = 2筑凫。
(此處延伸++i 和 i++ 的區(qū)別:
  ++i滑沧,是先將值賦值給其他值之后,在進行+1運算
  i++巍实,是先進行+1運算之后滓技,將值賦值給其他值
)
4. 執(zhí)行完a == 1返回true,會執(zhí)行a == 2棚潦,同理令漂,會調(diào)用ToPrimitive(a, Number),同上先調(diào)用valueOf方法丸边,在調(diào)用toString方法叠必,由于第一步,i = 2此時妹窖,ToPrimitive(a, Number) = 2纬朝, 也就是2 == 2, 此時i = 2 + 1。
5. 同上可以推導(dǎo) a == 3也返回true骄呼。故最終結(jié)果 a == 1 && a == 2 && a == 3返回true

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末共苛,一起剝皮案震驚了整個濱河市判没,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌隅茎,老刑警劉巖澄峰,帶你破解...
    沈念sama閱讀 212,718評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異辟犀,居然都是意外死亡俏竞,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評論 3 385
  • 文/潘曉璐 我一進店門堂竟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來魂毁,“玉大人,你說我怎么就攤上這事出嘹∈#” “怎么了?”我有些...
    開封第一講書人閱讀 158,207評論 0 348
  • 文/不壞的土叔 我叫張陵疚漆,是天一觀的道長。 經(jīng)常有香客問我刁赦,道長娶聘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,755評論 1 284
  • 正文 為了忘掉前任甚脉,我火速辦了婚禮丸升,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘牺氨。我一直安慰自己狡耻,他們只是感情好,可當我...
    茶點故事閱讀 65,862評論 6 386
  • 文/花漫 我一把揭開白布猴凹。 她就那樣靜靜地躺著夷狰,像睡著了一般。 火紅的嫁衣襯著肌膚如雪郊霎。 梳的紋絲不亂的頭發(fā)上沼头,一...
    開封第一講書人閱讀 50,050評論 1 291
  • 那天,我揣著相機與錄音书劝,去河邊找鬼进倍。 笑死,一個胖子當著我的面吹牛购对,可吹牛的內(nèi)容都是我干的猾昆。 我是一名探鬼主播,決...
    沈念sama閱讀 39,136評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼骡苞,長吁一口氣:“原來是場噩夢啊……” “哼垂蜗!你這毒婦竟也來了楷扬?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,882評論 0 268
  • 序言:老撾萬榮一對情侶失蹤么抗,失蹤者是張志新(化名)和其女友劉穎毅否,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體蝇刀,經(jīng)...
    沈念sama閱讀 44,330評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡螟加,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,651評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了吞琐。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捆探。...
    茶點故事閱讀 38,789評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖站粟,靈堂內(nèi)的尸體忽然破棺而出黍图,到底是詐尸還是另有隱情,我是刑警寧澤奴烙,帶...
    沈念sama閱讀 34,477評論 4 333
  • 正文 年R本政府宣布助被,位于F島的核電站,受9級特大地震影響切诀,放射性物質(zhì)發(fā)生泄漏揩环。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,135評論 3 317
  • 文/蒙蒙 一幅虑、第九天 我趴在偏房一處隱蔽的房頂上張望丰滑。 院中可真熱鬧,春花似錦倒庵、人聲如沸褒墨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,864評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽郁妈。三九已至,卻和暖如春认臊,著一層夾襖步出監(jiān)牢的瞬間圃庭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,099評論 1 267
  • 我被黑心中介騙來泰國打工失晴, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留剧腻,地道東北人。 一個月前我還...
    沈念sama閱讀 46,598評論 2 362
  • 正文 我出身青樓涂屁,卻偏偏與公主長得像书在,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子拆又,可洞房花燭夜當晚...
    茶點故事閱讀 43,697評論 2 351

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