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

JavaScript那些不經(jīng)意間發(fā)生的數(shù)據(jù)類型自動(dòng)轉(zhuǎn)換

 更新時(shí)間:2022年02月23日 10:11:47   作者:漫天瑩火  
JavaScript可以自由的進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換,但是更多的情況下,是由JavaScript自動(dòng)轉(zhuǎn)換的。本文就將為大家詳細(xì)講解那些不經(jīng)意間發(fā)生的數(shù)據(jù)類型轉(zhuǎn)換,感興趣的同學(xué)可以了解一下

JavaScript可以自由的進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換,也提供了多種顯式轉(zhuǎn)換的方式。但是更多的情況下,是由JavaScript自動(dòng)轉(zhuǎn)換的,當(dāng)然這些轉(zhuǎn)換遵循著一定的規(guī)則,了解數(shù)據(jù)類型自由轉(zhuǎn)換的規(guī)則是非常必要的。

數(shù)據(jù)類型

聊到數(shù)據(jù)類型轉(zhuǎn)換,就不得不提到 JavaScript 的數(shù)據(jù)類型:原始類型( Number , String , Boolean , undefinednull ,  Symbol),對(duì)象類型 (Object)。當(dāng)然Object有可以細(xì)分出 Array , Date , RegExp等等對(duì)象。

既然分為這么多種數(shù)據(jù)類型,每種數(shù)據(jù)類型肯定會(huì)有特定的用途,那么當(dāng)提供的值的數(shù)據(jù)類型與預(yù)期不符時(shí)要怎么辦呢?

比如我需要在控制語(yǔ)句中使用到 boolean 值,提供的值卻是 string 。當(dāng)然我們可以顯式轉(zhuǎn)換 Boolean( a : string) ,但是根據(jù)日常經(jīng)驗(yàn),我們知道其實(shí)不需要這么復(fù)雜,可以在控制語(yǔ)句中直接用這個(gè)string類型的變量 ,也可以達(dá)到預(yù)期的效果。如下:

可見(jiàn)自動(dòng)轉(zhuǎn)換方便很多,但是在這個(gè)過(guò)程中到底是按照什么規(guī)則處理的呢?

自動(dòng)轉(zhuǎn)換

什么時(shí)候會(huì)發(fā)生自動(dòng)轉(zhuǎn)換?

犀牛書上是這樣描述的: 當(dāng)JavaScript期望使用一個(gè)布爾值的時(shí)候,你可以提供任意類型值,JavaScript將根據(jù)需要自行轉(zhuǎn)換類型。一些值(真值)轉(zhuǎn)換為true , 一些值(假值)轉(zhuǎn)換為false 。這在其他類型中同樣適用:如果JavaScript期望使用一個(gè)字符串,它把給定的值轉(zhuǎn)換為字符串。如果JavaScript期望一個(gè)數(shù)字,它把給定的值轉(zhuǎn)換為數(shù)字(如果轉(zhuǎn)換結(jié)果毫無(wú)意義的話,將會(huì)返回NaN)。

簡(jiǎn)而言之就是:JavaScript有一些語(yǔ)句/運(yùn)算符對(duì)數(shù)據(jù)類型有要求,但我們提供的與預(yù)期不符時(shí),就會(huì)發(fā)生自動(dòng)類型轉(zhuǎn)換。

對(duì)數(shù)據(jù)類型有期待的表達(dá)式和運(yùn)算符

  • 期待boolean類型的:if 、 do while 、 while do 、 && 、 || 、  ! (與或非邏輯表達(dá)式)  、? :( 三目運(yùn)算符)
  • 期待number類型的 :  + - * / % (算數(shù)運(yùn)算符) 、  ++  --  (增量/減量運(yùn)算符) 、 > >= <  <= (數(shù)字比較)
  • 期待string的: + (字符串連接) 、 > >= <  <=  (字母排序比較)
  • 特殊的 : ==  、 !=  (不)相等運(yùn)算符,在檢測(cè)兩個(gè)操作數(shù)是否相等時(shí),會(huì)進(jìn)行類型轉(zhuǎn)換;(注意 :=== 、!== 是(不)嚴(yán)格相等運(yùn)算符,是不會(huì)進(jìn)行類型轉(zhuǎn)換的)

需要說(shuō)明的是,1中當(dāng)然可以傳入表達(dá)式,但是表達(dá)式返回的結(jié)果也肯定會(huì)返回boolean類型的值,或者返回值被轉(zhuǎn)換為boolean;2和3有一些重復(fù)的運(yùn)算符 : + 、 > 、  >= 、 <  、 <= ,這些運(yùn)算符在不同場(chǎng)景下發(fā)生自動(dòng)轉(zhuǎn)換的時(shí)候,會(huì)有不同的優(yōu)先級(jí)。

運(yùn)算符在不同場(chǎng)景的轉(zhuǎn)換優(yōu)先級(jí)

+

// + 有兩種作用:算數(shù)運(yùn)算和字符串連接。所以期待的是數(shù)字和字符串! 
// 1、兩個(gè)操作數(shù)同為數(shù)字,或者同為字符串,不需要進(jìn)行轉(zhuǎn)換
    1 + 1   // 2  
    '1' + '1'  // '11'  
// 2、有一個(gè)操作數(shù)是字符串,則另外一個(gè)也會(huì)轉(zhuǎn)換為字符串
    '1' + 1   // "11"
    '1' + null   //  "1null"
    '1' + {}   //  "1[object Object]"
    '1' + new Date()  //  "1Wed Jun 20 2018 11:49:55 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)"
// 3、如果有一個(gè)操作數(shù)是對(duì)象的話,會(huì)轉(zhuǎn)化為原始值(除了Date對(duì)象是調(diào)用toString()方式轉(zhuǎn)換 , 其他對(duì)象都會(huì)調(diào)用 valueOf() 進(jìn)行轉(zhuǎn)換 , 但是由于多數(shù)對(duì)象只是簡(jiǎn)單的繼承了valueOf() , 只會(huì)返回對(duì)象,而不是一個(gè)原始值,所以會(huì)再調(diào)用toString進(jìn)行轉(zhuǎn)換) , 所以這里可以簡(jiǎn)單的理解為:都會(huì)轉(zhuǎn)換為字符串 。 另一個(gè)操作數(shù)也會(huì)轉(zhuǎn)換為字符串
    1 + {}   // "1[object Object]"
    1 + new Date()  //  "1Wed Jun 20 2018 11:56:56 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)"
    1 + []   //  "1"
// 4、 其他情況都會(huì)轉(zhuǎn)換為數(shù)字
    1 + null  // 1
    1 + undefined   // NaN

從例子中可以看到,+ 的轉(zhuǎn)換其實(shí)是優(yōu)先轉(zhuǎn)換為字符串的,如果操作數(shù)中又字符串或者對(duì)象(對(duì)象在這里會(huì)轉(zhuǎn)換為字符串),則會(huì)按照 字符串連接進(jìn)行操作的。從例子的第3個(gè)可以看到,第一個(gè)操作數(shù)都是數(shù)字,但是會(huì)轉(zhuǎn)化為字符串。例子中的第4個(gè),沒(méi)有對(duì)象和字符串,nullundefined 都轉(zhuǎn)換為 數(shù)字進(jìn)行算數(shù)運(yùn)算,其中 undefined -> number 會(huì)返回 NaN , 所以計(jì)算結(jié)果為 NaN。

+ 還有特殊的用法,就是轉(zhuǎn)換為數(shù)字,如下。會(huì)將 + 后面的操作數(shù)轉(zhuǎn)換為數(shù)字,具體的轉(zhuǎn)換規(guī)則后續(xù)會(huì)說(shuō)明。

+ null   //  0
+ undefined  //  NaN
+ {}  //  NaN
+ new Date()  //  1529467646682
+ ["5"]  //  5
+ "4"  //  4

> 、>= 、< 、<= 

> 、>= 、< 、<= 這些比較運(yùn)算符的規(guī)則和 + 類似,不過(guò)是會(huì)優(yōu)先轉(zhuǎn)換為數(shù)字進(jìn)行比較。

// 作用 : 比較數(shù)值大小或者再字母表中的位置。也是期待數(shù)字和字符串!
1、兩個(gè)操作數(shù)中只要有一個(gè)不是字符串,則兩個(gè)值都轉(zhuǎn)為數(shù)字
 "3" > "11"    //  true   字符串比較
  3 > "11"      // false   11 轉(zhuǎn)換為數(shù)字
 true > '0'    // true true 和 ‘0' 都轉(zhuǎn)換為數(shù)字 
2、對(duì)象同樣會(huì)轉(zhuǎn)換為原始值(不過(guò)這里的Date對(duì)象也是優(yōu)先調(diào)用valueOf ,返回的是毫秒數(shù),其他的和上述 + 的一樣),如果轉(zhuǎn)換后有一個(gè)字不是字符串,則兩個(gè)值也都需要轉(zhuǎn)換為數(shù)字
    1000 > new Date()  // false
    100000000000000000000000 > new Date()  //  true   date對(duì)象轉(zhuǎn)換為數(shù)字
    "100000000000000000000000" > new Date()  //  true  左值也隨著 date對(duì)象一起轉(zhuǎn)換為數(shù)字
    '11' > ["3"]  //  false  數(shù)組轉(zhuǎn)為字符串,所以這里是字符串比較

這里需要注意的是,只要在轉(zhuǎn)換為數(shù)字的過(guò)程中,有一個(gè)值是 NaN ,那么比較的結(jié)果肯定是 false

== 、 != 

== 、 != (不)相等運(yùn)算符是不嚴(yán)格的比較,所以,如果兩個(gè)操作數(shù)不是同一類型,那么會(huì)嘗試進(jìn)行一些類型轉(zhuǎn)換,然后進(jìn)行比較。有以下規(guī)則和類型轉(zhuǎn)換:

  • 一個(gè)值是 undefined,一個(gè)值是null,則相等
  • 一個(gè)值是數(shù)字,一個(gè)值是字符串,則字符串轉(zhuǎn)換為數(shù)字進(jìn)行比較
  • truefalse 會(huì)分別轉(zhuǎn)換為 10 
  • 一個(gè)值是字符串或者數(shù)字,另一個(gè)是對(duì)象,對(duì)象轉(zhuǎn)換為原始值(Date類只調(diào)用toString,其他的和之前的一致),然后進(jìn)行比較。
  • 其他的比較,全是 false
null == undefined  // true  1
null == 0    //  false  5
1 == '1'  //  true   2
1 == true  //  true  3 
2 == true  //  false  3
1 == [1]  // true  4
'1' == ['1']  // true  4   數(shù)組轉(zhuǎn)為字符串
1 == ['1']  //  true  4  數(shù)組轉(zhuǎn)為字符串再轉(zhuǎn)為數(shù)字

對(duì)象包裝

還有一種自動(dòng)轉(zhuǎn)換也很容易被忽略,但是經(jīng)常見(jiàn)到。那就是對(duì)象包裝。

思考一個(gè)問(wèn)題,為什么數(shù)字是原始類型,卻可以使用 toString 方法? 只有對(duì)象才會(huì)有方法的,為什么數(shù)字卻可以使用?

let x = 1
x.toString()  //   "1"

 因?yàn)樵趚需要使用方法的時(shí)候,JavaScript會(huì)通過(guò)調(diào)用 new Number(x) 的方式將它暫時(shí)轉(zhuǎn)換為對(duì)象,它繼承了Number對(duì)象的方法,所以就可以調(diào)用toString了。同樣的還有字符串、布爾值,也是通過(guò)各種的構(gòu)造函數(shù)進(jìn)行轉(zhuǎn)換。這也是為什么undefinednull,不可以使用toString的原因,因?yàn)樗鼈儧](méi)有構(gòu)造函數(shù)。

x = null
x.toString()
//VM289:1 Uncaught TypeError: Cannot read property 'toString' of //null
//   at <anonymous>:1:3
//(anonymous) @ VM289:1


x = undefined
x.toString()

//VM305:1 Uncaught TypeError: Cannot read property 'toString' of //undefined
//    at <anonymous>:1:3

目前我所了解的自動(dòng)轉(zhuǎn)換就只有這么多,后續(xù)再繼續(xù)補(bǔ)充。那么自動(dòng)轉(zhuǎn)換的過(guò)程中,又有哪些規(guī)則呢?  

自動(dòng)轉(zhuǎn)換規(guī)則

any -> boolean

在其他類型的值轉(zhuǎn)換為 boolean 時(shí),只有這幾個(gè)會(huì)轉(zhuǎn)換為 false ,其他都是 trueundefined 、 null"" 、 0 、-0NaN。

Boolean(0)  //  false
Boolean("") //false
Boolean(NaN)  //false
Boolean(undefined)  //false
Boolean(null)  // false

// 空對(duì)象 空數(shù)組 空函數(shù) 都會(huì)true
Boolean({})  // true
Boolean([])   //true
Boolean(function () {})   // true

// 此時(shí)是一個(gè)boolean對(duì)象,而不是原始值,所以是true
Boolean(new Boolean(false))  // true

any -> number

在其他類型的值轉(zhuǎn)換為number是,就復(fù)雜一些:

1.boolean -> number 

true ->  1

false -> 0

2.string -> number

由數(shù)字組成的字符串,可以直接轉(zhuǎn)換為數(shù)字,開(kāi)始和結(jié)尾的空格都可以忽略。不符合的字符串會(huì)返回NaN。

+''   //  0  空字符串
+'100'   //  100
+'   100  '   //  100 忽略前后空格
+'   100aa'  //  NaN   有其他非數(shù)字

備注:這里的規(guī)則是自動(dòng)轉(zhuǎn)換的規(guī)則,如果是顯示轉(zhuǎn)換的話,構(gòu)造函數(shù)Number() 和此規(guī)則一致,而window.parseInt()  window.parseFloat的解析規(guī)則則不一樣。如下

window.parseInt('  100a  ')   //  100
window.parseFloat(' 100.11a') // 100.11

3.對(duì)象 -> number

對(duì)象會(huì)先嘗試調(diào)用 valueOf 返回原始值,如果沒(méi)有則調(diào)用toString返回原始值,再進(jìn)行轉(zhuǎn)換返回??磶讉€(gè)例子

+new Date()  //  1529483712712  date對(duì)象的valueOf返回毫米數(shù),即為數(shù)字
+[]  //  0   數(shù)組valueOf為它自己,再調(diào)用toString 返回 “” ,空字符串轉(zhuǎn)換為數(shù)字為0
+['1']  //  1  同樣toString  返回 “1” , 轉(zhuǎn)換為數(shù)字為 1
+['1','2']  // NaN  toString 返回 “1,2”  轉(zhuǎn)換為數(shù)字 NaN
+{}  //  NaN   toString [Object,Object] , 轉(zhuǎn)換為數(shù)字 NaN

4.undefined  null 

null -> 0

undefined -> NaN

any -> string

1.null undefined boolean  number

這幾個(gè)原始類型的轉(zhuǎn)換非常簡(jiǎn)單,就是將自身用引號(hào)包裹而已。

'' + 1  //  "1"
'' + true  //  "true"
'' + undefined  //  "undefined"
'' + null  //   "null"

2.object -> string 

和對(duì)象轉(zhuǎn)化為數(shù)字類似,不過(guò)是先調(diào)用toString,在調(diào)用valueOf。

'' + {}  //   "[object Object]"
'' + []   //  ""
'' + [1,2,3]  //  "1,2,3"
'' + function() {}  //  "function () {}"
'' + new Date()  //  "Wed Jun 20 2018 16:50:56 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間)"

可以看出不同的對(duì)象差別挺大的,數(shù)組會(huì)將每個(gè)元素用逗號(hào)分開(kāi),生成字符串,date對(duì)象toString返回的是中國(guó)標(biāo)準(zhǔn)時(shí)間,從這里就可以看過(guò)和轉(zhuǎn)化成數(shù)字的不同邏輯了,先嘗試 toString  不行才再 valueOf。

總結(jié)

自動(dòng)類型轉(zhuǎn)換真的非常常見(jiàn),常用的一些便捷的轉(zhuǎn)類型的方式,都是依靠自動(dòng)轉(zhuǎn)換產(chǎn)生的。比如 轉(zhuǎn)數(shù)字 + x   、  x - 0  ,轉(zhuǎn)字符串 :   "" + x  等等?,F(xiàn)在總算知道為什么可以這樣便捷轉(zhuǎn)換。

以上就是JavaScript那些不經(jīng)意間發(fā)生的數(shù)據(jù)類型自動(dòng)轉(zhuǎn)換的詳細(xì)內(nèi)容,更多關(guān)于JavaScript數(shù)據(jù)類型轉(zhuǎn)換的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 初學(xué)Javascript的一些總結(jié)

    初學(xué)Javascript的一些總結(jié)

    對(duì)于新手是個(gè)不錯(cuò)的必須要理解的東西
    2008-11-11
  • Three.js源碼閱讀筆記(基礎(chǔ)的核心Core對(duì)象)

    Three.js源碼閱讀筆記(基礎(chǔ)的核心Core對(duì)象)

    Three.js是一個(gè)比較偉大的webgl開(kāi)源庫(kù),它簡(jiǎn)化了瀏覽器3D編程,使得使用JavaScript在瀏覽器中創(chuàng)建復(fù)雜的場(chǎng)景變得容易很多接下來(lái)先從最基礎(chǔ)的核心(Core)對(duì)象開(kāi)始,感興趣的朋友可以參考下
    2012-12-12
  • JavaScript基本編碼模式小結(jié)

    JavaScript基本編碼模式小結(jié)

    本文中筆者整理的這些模式包含了編寫JavaScript代碼時(shí)一些常用的方法或者小技巧,可以幫助初學(xué)JavaScript的同學(xué)迅速提升代碼質(zhì)量
    2012-05-05
  • JavaScript DOM學(xué)習(xí)第八章 表單錯(cuò)誤提示

    JavaScript DOM學(xué)習(xí)第八章 表單錯(cuò)誤提示

    這一章詳細(xì)介紹的表單錯(cuò)誤提示的方法比那種大多數(shù)使用警告框的方法要好的多。
    2010-02-02
  • Javascript學(xué)習(xí)筆記之?dāng)?shù)組的構(gòu)造函數(shù)

    Javascript學(xué)習(xí)筆記之?dāng)?shù)組的構(gòu)造函數(shù)

    這篇文章主要介紹了Javascript數(shù)組的構(gòu)造函數(shù)及常見(jiàn)的操作,講解的十分詳細(xì),這里推薦給大家
    2014-11-11
  • 最新評(píng)論