欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

'2'>'10'==true?解析JS如何進(jìn)行隱式類型轉(zhuǎn)換

 更新時(shí)間:2023年09月03日 15:48:10   作者:南玖  
這篇文章主要為大家介紹了'2'>'10'==true?解析JS如何進(jìn)行隱式類型轉(zhuǎn)換示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

前言

'2'>'10'返回的true,可能很多人都不是很能理解吧? 在js中,當(dāng)運(yùn)算符在運(yùn)算時(shí),如果兩邊數(shù)據(jù)不統(tǒng)一,CPU就無法計(jì)算,這時(shí)我們編譯器會(huì)自動(dòng)將運(yùn)算符兩邊的數(shù)據(jù)做一個(gè)數(shù)據(jù)類型轉(zhuǎn)換,轉(zhuǎn)成一樣的數(shù)據(jù)類型再計(jì)算。 這種無需程序員手動(dòng)轉(zhuǎn)換,而由編譯器自動(dòng)轉(zhuǎn)換的方式就稱為隱式轉(zhuǎn)換。

想要知道'2'>'10'為什么是true,我們得先來了解一下JavaScript的隱式類型轉(zhuǎn)換規(guī)則。

隱式類型轉(zhuǎn)換規(guī)則

1. == 操作符的強(qiáng)制類型轉(zhuǎn)換規(guī)則?

  • 字符串和數(shù)字之間的相等比較,將字符串轉(zhuǎn)換為數(shù)字之后再進(jìn)行比較。
  • 其他類型和布爾類型之間的相等比較,先將布爾值轉(zhuǎn)換為數(shù)字后,再應(yīng)用其他規(guī)則進(jìn)行比較。
  • null 和 undefined 之間的相等比較,結(jié)果為真。其他值和它們進(jìn)行比較都返回假值。
  • 對象和非對象之間的相等比較,對象先調(diào)用 ToPrimitive 抽象操作后,再進(jìn)行比較。
  • 如果一個(gè)操作值為 NaN ,則相等比較返回 false( NaN 本身也不等于 NaN )。
  • 如果兩個(gè)操作值都是對象,則比較它們是不是指向同一個(gè)對象。如果兩個(gè)操作數(shù)都指向同一個(gè)對象,則相等操作符返回true,否則,返回 false。

2.遞增遞減操作符(前置與后置)、一元正負(fù)操作符

這些操作符適用于任何數(shù)據(jù)類型的值,針對不同類型的值,該操作符遵循以下規(guī)則(經(jīng)過對比發(fā)現(xiàn),其規(guī)則與Number()規(guī)則基本相同):

  • 如果是包含有效數(shù)字字符的字符串,先將其轉(zhuǎn)換為數(shù)字值(轉(zhuǎn)換規(guī)則同Number()),在執(zhí)行加減1的操作,字符串變量變?yōu)閿?shù)值變量。
  • 如果是不包含有效數(shù)字字符的字符串,將變量的值設(shè)置為NaN,字符串變量變成數(shù)值變量。
  • 如果是布爾值false,先將其轉(zhuǎn)換為0再執(zhí)行加減1的操作,布爾值變量編程數(shù)值變量。
  • 如果是布爾值true,先將其轉(zhuǎn)換為1再執(zhí)行加減1的操作,布爾值變量變成數(shù)值變量。
  • 如果是浮點(diǎn)數(shù)值,執(zhí)行加減1的操作。
  • 如果是對象,先調(diào)用對象的valueOf()方法,然后對該返回值應(yīng)用前面的規(guī)則。如果結(jié)果是NaN,則調(diào)用toString()方法后再應(yīng)用前面的規(guī)則。對象變量變成數(shù)值變量。

3.加法運(yùn)算操作符

加號(hào)運(yùn)算操作符在Javascript也用于字符串連接符,所以加號(hào)操作符的規(guī)則分兩種情況:
如果兩個(gè)操作值都是數(shù)值,其規(guī)則為:

  • 如果一個(gè)操作數(shù)為NaN,則結(jié)果為NaN
  • 如果是Infinity+Infinity,結(jié)果是Infinity
  • 如果是-Infinity+(-Infinity),結(jié)果是-Infinity
  • 如果是Infinity+(-Infinity),結(jié)果是NaN
  • 如果是+0+(+0),結(jié)果為+0
  • 如果是(-0)+(-0),結(jié)果為-0
  • 如果是(+0)+(-0),結(jié)果為+0

如果有一個(gè)操作值為字符串,則:

  • 如果兩個(gè)操作值都是字符串,則將它們拼接起來
  • 如果只有一個(gè)操作值為字符串,則將另外操作值轉(zhuǎn)換為字符串,然后拼接起來
  • 如果一個(gè)操作數(shù)是對象、數(shù)值或者布爾值,則調(diào)用toString()方法取得字符串值,然后再應(yīng)用前面的字符串規(guī)則。對于undefined和null,分別調(diào)用String()顯式轉(zhuǎn)換為字符串。
  • 可以看出,加法運(yùn)算中,如果有一個(gè)操作值為字符串類型,則將另一個(gè)操作值轉(zhuǎn)換為字符串,最后連接起來。

4. 乘除、減號(hào)運(yùn)算符、取模運(yùn)算符

這些操作符針對的是運(yùn)算,所以他們具有共同性:如果操作值之一不是數(shù)值,則被隱式調(diào)用Number()函數(shù)進(jìn)行轉(zhuǎn)換。

5.邏輯操作符(!、&&、||)

邏輯非(?。┎僮鞣紫韧ㄟ^Boolean()函數(shù)將它的操作值轉(zhuǎn)換為布爾值,然后求反。邏輯與(&&)操作符,如果一個(gè)操作值不是布爾值時(shí),遵循以下規(guī)則進(jìn)行轉(zhuǎn)換:

  • 如果第一個(gè)操作數(shù)經(jīng)Boolean()轉(zhuǎn)換后為true,則返回第二個(gè)操作值,否則返回第一個(gè)值(不是Boolean()轉(zhuǎn)換后的值)
  • 如果有一個(gè)操作值為null,返回null
  • 如果有一個(gè)操作值為NaN,返回NaN
  • 如果有一個(gè)操作值為undefined,返回undefined
    邏輯或(||)操作符,如果一個(gè)操作值不是布爾值,遵循以下規(guī)則:
  • 如果第一個(gè)操作值經(jīng)Boolean()轉(zhuǎn)換后為false,則返回第二個(gè)操作值,否則返回第一個(gè)操作值(不是Boolean()轉(zhuǎn)換后的值)
  • 對于undefined、null和NaN的處理規(guī)則與邏輯與(&&)相同

6.關(guān)系操作符(<, >, <=, >=)

與上述操作符一樣,關(guān)系操作符的操作值也可以是任意類型的,所以使用非數(shù)值類型參與比較時(shí)也需要系統(tǒng)進(jìn)行隱式類型轉(zhuǎn)換:

  • 如果兩個(gè)操作值都是數(shù)值,則進(jìn)行數(shù)值比較
  • 如果兩個(gè)操作值都是字符串,則比較字符串對應(yīng)的字符編碼值
  • 如果只有一個(gè)操作值是數(shù)值,則將另一個(gè)操作值轉(zhuǎn)換為數(shù)值,進(jìn)行數(shù)值比較
  • 如果一個(gè)操作數(shù)是對象,則調(diào)用valueOf()方法(如果對象沒有valueOf()方法則調(diào)用toString()方法),得到的結(jié)果按照前面的規(guī)則執(zhí)行比較
  • 如果一個(gè)操作值是布爾值,則將其轉(zhuǎn)換為數(shù)值,再進(jìn)行比較
    注:NaN是非常特殊的值,它不和任何類型的值相等,包括它自己,同時(shí)它與任何類型的值比較大小時(shí)都返回false。

7. 其他值到字符串的轉(zhuǎn)換規(guī)則?

  • Null 和 Undefined 類型 ,null 轉(zhuǎn)換為 “null”,undefined 轉(zhuǎn)換為 “undefined”,
  • Boolean 類型,true 轉(zhuǎn)換為 “true”,false 轉(zhuǎn)換為 “false”。
  • Number 類型的值直接轉(zhuǎn)換,不過那些極小和極大的數(shù)字會(huì)使用指數(shù)形式。
  • Symbol 類型的值直接轉(zhuǎn)換,但是只允許顯式強(qiáng)制類型轉(zhuǎn)換,使用隱式強(qiáng)制類型轉(zhuǎn)換會(huì)產(chǎn)生錯(cuò)誤。
  • 對普通對象來說,除非自行定義 toString() 方法,否則會(huì)調(diào)用 toString()(Object.prototype.toString())來返回內(nèi)部屬性 [[Class]] 的值,如”[object Object]”。如果對象有自己的 toString() 方法,字符串化時(shí)就會(huì)調(diào)用該方法并使用其返回值。

8. 其他值到數(shù)字值的轉(zhuǎn)換規(guī)則?

  • Undefined 類型的值轉(zhuǎn)換為 NaN。
  • Null 類型的值轉(zhuǎn)換為 0。
  • Boolean 類型的值,true 轉(zhuǎn)換為 1,false 轉(zhuǎn)換為 0。
  • String 類型的值轉(zhuǎn)換如同使用 Number() 函數(shù)進(jìn)行轉(zhuǎn)換,如果包含非數(shù)字值則轉(zhuǎn)換為 NaN,空字符串為 0。
  • Symbol 類型的值不能轉(zhuǎn)換為數(shù)字,會(huì)報(bào)錯(cuò)。
  • 對象(包括數(shù)組)會(huì)首先被轉(zhuǎn)換為相應(yīng)的基本類型值,如果返回的是非數(shù)字的基本類型值,則再遵循以上規(guī)則將其強(qiáng)制轉(zhuǎn)換為數(shù)字。

為了將值轉(zhuǎn)換為相應(yīng)的基本類型值,抽象操作 ToPrimitive 會(huì)首先(通過內(nèi)部操作 DefaultValue)檢查該值是否有valueOf()方法。如果有并且返回基本類型值,就使用該值進(jìn)行強(qiáng)制類型轉(zhuǎn)換。如果沒有就使用 toString() 的返回值(如果存在)來進(jìn)行強(qiáng)制類型轉(zhuǎn)換。

如果 valueOf() 和 toString() 均不返回基本類型值,會(huì)產(chǎn)生 TypeError 錯(cuò)誤。

9. 其他值到布爾類型的值的轉(zhuǎn)換規(guī)則?

以下這些是假值: undefined、 null、 false、 +0、-0 和 NaN 、“”

假值的布爾強(qiáng)制類型轉(zhuǎn)換結(jié)果為 false。從邏輯上說,假值列表以外的都應(yīng)該是真值。

總結(jié)

  • null、undefined 是相等的,且等于自身
  • false 、 0、 '' 、 [] 是相等的
  • NaN、{} 和什么都不相等,自己跟自己都不相等
NaN == NaN  //false
NaN == undefined //false
NaN == false //false
NaN == null //false
NaN==[]  //false
NaN==''  //false
NaN=={}  //false
false == false  //true
false == undefined  //false
false == null  //false
false == []  //true
false == {}  //false
false == ''  //true
undefined == undefined //true
undefined == null  //true
undefined == false //false
undefined == [] //false
undefined == {}  //false
undefined == '' //false
null == null   //true
null == NaN  //false  
null == []  //false
null == {}  //false
null == undefined  //true
0==false    //true   
0 == []  //true
0 == {}  //false
0 == null  //false
0 == undefined //false
0 == '' //true
0 == NaN //false
false == []  //true
false == {}  //false
false == null  //false
false == undefined  //false
false == ''  //true
false == NaN  //false
[]=={} //false
Boolean([])   //true
Boolean({})   //true
Boolean(null)  //false
Boolean(NaN) //false
Boolean(undefined)  //false
Boolean('')  //false
Boolean(0)  //false
Number(undefined)  //NaN
Number({})    //NaN
Number(NaN)  //NaN
Number('')  //0
Number([])    //0
Number(false)  //0
Number(null)  //0

'2'>'10'為什么是true?

上面我們列了這么多轉(zhuǎn)換的規(guī)則,那么這道題我們就可以在上面這些規(guī)則中找到答案了,首先找到關(guān)系操作符,該規(guī)則中的第二點(diǎn)是兩個(gè)操作符都是字符串的話,則比較字符串對應(yīng)的字符編碼值,按我們常規(guī)思維是不是會(huì)覺得他會(huì)轉(zhuǎn)為數(shù)字再比較,然后2>10,返回false,然而并不是的,是不是覺得JavaScript很坑??。JavaScript中用charCodeAt()來獲取字符編碼

console.log('2'>'10') // true
//首先將操作符兩邊都轉(zhuǎn)為字符編碼再進(jìn)行比較
'2'.charCodeAt() //50
'10'.charCodeAt() // 49
// 所以 '2'>'10' 會(huì)返回true

我們再來看幾道有趣(很坑)的題

1.復(fù)雜數(shù)據(jù)類型轉(zhuǎn)string

先調(diào)用valueOf()獲取原始值,如果原始值不是string類型,則調(diào)用toString()轉(zhuǎn)成string

console.log([1,2] == '1,2')  //true
[1,2].toString() // '1,2'
var a = {}
console.log(a.toString()) // "[object Object]"
console.log(a == "[object Object]") //true

解析:

先將左邊數(shù)據(jù)類型轉(zhuǎn)成string,然后兩邊都是string,再比較字符編碼值

2.邏輯非隱式轉(zhuǎn)換與關(guān)系運(yùn)算符隱式轉(zhuǎn)換

console.log([] == 0) // true
console.log(![] == 0) // true 
console.log([] == ![])  // true  是不是覺得很離譜???
console.log([] == [])  //false
console.log({} == !{}) //false
console.log({} == {})  // false

看到這些結(jié)果是不是很吃驚,是的我也覺得很吃驚,簡直深坑。玩笑歸玩笑,我們還是一起來看看到底是為什么吧??!

解析:

console.log([] == 0) // true
/*關(guān)系運(yùn)算符(3)如果只有一個(gè)操作值是數(shù)值,則將另一個(gè)操作值轉(zhuǎn)換為數(shù)值,進(jìn)行數(shù)值比較
原理:
1.[].valueOf().toString() 得到字符串""
2.將""轉(zhuǎn)為數(shù)字Number("") 得到數(shù)字0
所以 [] == 0 成立
*/
console.log(![] == 0) // true 
/*
原理:與上面類似,只是邏輯運(yùn)算符優(yōu)先級(jí)高于關(guān)系運(yùn)算符,所以先執(zhí)行![] 得到false
false == 0 成立
*/
console.log([] == ![])  // true  
/*
上面我們知道了 []==0 ![] == 0 
所以 [] == ![]
*/
console.log([] == [])  //false
/*
引用數(shù)據(jù)類型數(shù)據(jù)存在堆中,棧中存儲(chǔ)的是它們的地址,兩個(gè)[]地址肯定不一樣,所以是false
*/
console.log({} == !{}) //false
/*
原理:
1. {}.valueOf().toString()  得到"[object,Object]"
2. !{} == false
3. Number("[object,Object]") // NaN
     Number(false) //0
4. NaN != 0
*/
console.log({} == {})  // false
/*
引用數(shù)據(jù)類型數(shù)據(jù)存在堆中,棧中存儲(chǔ)的是它們的地址,所以肯定不一樣
*/

JavaScript真值表

以上就是'2'&gt;'10'==true?解析JS如何進(jìn)行隱式類型轉(zhuǎn)換的詳細(xì)內(nèi)容,更多關(guān)于JS隱式類型轉(zhuǎn)換的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評論