'2'>'10'傳回的true,可能很多人都不是很能了解吧? 在js中,當運算符在運算時,如果兩邊資料不統一,CPU就無法計算,這時我們編譯器會自動将運算符兩邊的資料做一個資料類型轉換,轉成一樣的資料類型再計算。 這種無需程式員手動轉換,而由編譯器自動轉換的方式就稱為隐式轉換。
如果這篇文章有幫助到你,❤️關注+點贊❤️鼓勵一下作者,文章公衆号首發~
想要知道'2'>'10'為什麼是true,我們得先來了解一下JavaScript的隐式類型轉換規則。
字元串和數字之間的相等比較,将字元串轉換為數字之後再進行比較。
其他類型和布爾類型之間的相等比較,先将布爾值轉換為數字後,再應用其他規則進行比較。
null 和 undefined 之間的相等比較,結果為真。其他值和它們進行比較都傳回假值。
對象和非對象之間的相等比較,對象先調用 ToPrimitive 抽象操作後,再進行比較。
如果一個操作值為 NaN ,則相等比較傳回 false( NaN 本身也不等于 NaN )。
如果兩個操作值都是對象,則比較它們是不是指向同一個對象。如果兩個操作數都指向同一個對象,則相等操作符傳回true,否則,傳回 false。
這些操作符适用于任何資料類型的值,針對不同類型的值,該操作符遵循以下規則(經過對比發現,其規則與Number()規則基本相同):
如果是包含有效數字字元的字元串,先将其轉換為數字值(轉換規則同Number()),在執行加減1的操作,字元串變量變為數值變量。
如果是不包含有效數字字元的字元串,将變量的值設定為NaN,字元串變量變成數值變量。
如果是布爾值false,先将其轉換為0再執行加減1的操作,布爾值變量程式設計數值變量。
如果是布爾值true,先将其轉換為1再執行加減1的操作,布爾值變量變成數值變量。
如果是浮點數值,執行加減1的操作。
如果是對象,先調用對象的valueOf()方法,然後對該傳回值應用前面的規則。如果結果是NaN,則調用toString()方法後再應用前面的規則。對象變量變成數值變量。
加号運算操作符在Javascript也用于字元串連接配接符,是以加号操作符的規則分兩種情況:
如果兩個操作值都是數值,其規則為:
如果一個操作數為NaN,則結果為NaN
如果是Infinity+Infinity,結果是Infinity
如果是-Infinity+(-Infinity),結果是-Infinity
如果是Infinity+(-Infinity),結果是NaN
如果是+0+(+0),結果為+0
如果是(-0)+(-0),結果為-0
如果是(+0)+(-0),結果為+0
如果有一個操作值為字元串,則:
如果兩個操作值都是字元串,則将它們拼接起來
如果隻有一個操作值為字元串,則将另外操作值轉換為字元串,然後拼接起來
如果一個操作數是對象、數值或者布爾值,則調用toString()方法取得字元串值,然後再應用前面的字元串規則。對于undefined和null,分别調用String()顯式轉換為字元串。
可以看出,加法運算中,如果有一個操作值為字元串類型,則将另一個操作值轉換為字元串,最後連接配接起來。
這些操作符針對的是運算,是以他們具有共同性:如果操作值之一不是數值,則被隐式調用Number()函數進行轉換。
邏輯非(!)操作符首先通過Boolean()函數将它的操作值轉換為布爾值,然後求反。
邏輯與(&&)操作符,如果一個操作值不是布爾值時,遵循以下規則進行轉換:
如果第一個操作數經Boolean()轉換後為true,則傳回第二個操作值,否則傳回第一個值(不是Boolean()轉換後的值)
如果有一個操作值為null,傳回null
如果有一個操作值為NaN,傳回NaN
如果有一個操作值為undefined,傳回undefined
邏輯或(||)操作符,如果一個操作值不是布爾值,遵循以下規則:
如果第一個操作值經Boolean()轉換後為false,則傳回第二個操作值,否則傳回第一個操作值(不是Boolean()轉換後的值)
對于undefined、null和NaN的處理規則與邏輯與(&&)相同
與上述操作符一樣,關系操作符的操作值也可以是任意類型的,是以使用非數值類型參與比較時也需要系統進行隐式類型轉換:
如果兩個操作值都是數值,則進行數值比較
如果兩個操作值都是字元串,則比較字元串對應的字元編碼值
如果隻有一個操作值是數值,則将另一個操作值轉換為數值,進行數值比較
如果一個操作數是對象,則調用valueOf()方法(如果對象沒有valueOf()方法則調用toString()方法),得到的結果按照前面的規則執行比較
如果一個操作值是布爾值,則将其轉換為數值,再進行比較
注:NaN是非常特殊的值,它不和任何類型的值相等,包括它自己,同時它與任何類型的值比較大小時都傳回false。
Null 和 Undefined 類型 ,null 轉換為 “null”,undefined 轉換為 “undefined”,
Boolean 類型,true 轉換為 “true”,false 轉換為 “false”。
Number 類型的值直接轉換,不過那些極小和極大的數字會使用指數形式。
Symbol 類型的值直接轉換,但是隻允許顯式強制類型轉換,使用隐式強制類型轉換會産生錯誤。
對普通對象來說,除非自行定義 toString() 方法,否則會調用 toString()(Object.prototype.toString())來傳回内部屬性 [[Class]] 的值,如”[object Object]”。如果對象有自己的 toString() 方法,字元串化時就會調用該方法并使用其傳回值。
Undefined 類型的值轉換為 NaN。
Null 類型的值轉換為 0。
Boolean 類型的值,true 轉換為 1,false 轉換為 0。
String 類型的值轉換如同使用 Number() 函數進行轉換,如果包含非數字值則轉換為 NaN,空字元串為 0。
Symbol 類型的值不能轉換為數字,會報錯。
對象(包括數組)會首先被轉換為相應的基本類型值,如果傳回的是非數字的基本類型值,則再遵循以上規則将其強制轉換為數字。
為了将值轉換為相應的基本類型值,抽象操作 ToPrimitive 會首先(通過内部操作 DefaultValue)檢查該值是否有valueOf()方法。如果有并且傳回基本類型值,就使用該值進行強制類型轉換。如果沒有就使用 toString() 的傳回值(如果存在)來進行強制類型轉換。
如果 valueOf() 和 toString() 均不傳回基本類型值,會産生 TypeError 錯誤。
以下這些是假值: undefined、 null、 false、 +0、-0 和 NaN 、“”
假值的布爾強制類型轉換結果為 false。從邏輯上說,假值清單以外的都應該是真值。
null、undefined 是相等的,且等于自身
false 、 0、 '' 、 [] 是相等的
NaN、{} 和什麼都不相等,自己跟自己都不相等
上面我們列了這麼多轉換的規則,那麼這道題我們就可以在上面這些規則中找到答案了,首先找到關系操作符,該規則中的第二點是兩個操作符都是字元串的話,則比較字元串對應的字元編碼值,按我們正常思維是不是會覺得他會轉為數字再比較,然後2>10,傳回false,然而并不是的,是不是覺得JavaScript很坑🦢。<code>JavaScript</code>中用<code>charCodeAt()</code>來擷取字元編碼
先調用<code>valueOf()</code>擷取原始值,如果原始值不是string類型,則調用<code>toString()</code>轉成string
解析:
先将左邊資料類型轉成string,然後兩邊都是string,再比較字元編碼值
看到這些結果是不是很吃驚,是的我也覺得很吃驚,簡直深坑。玩笑歸玩笑,我們還是一起來看看到底是為什麼吧!!
我是<code>南玖</code>,感謝各位的:「點贊、關注和評論」,我們下期見!
作者:前端南玖
出處:https://www.cnblogs.com/songyao666/
-------------------------------------------
個性簽名:智者創造機會,強者把握機會,弱者坐等機會。做一個靈魂有趣的人!
如果覺得這篇文章對你有小小的幫助的話,可以關注下方公衆号,在該公衆号同樣會推送技術文章給大家,謝謝~
歡迎加入前端技術交流群:928029210