亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

JavaScript可以自由的進(jìn)行數(shù)據(jù)類型轉(zhuǎn)換,也提供了多種顯式轉(zhuǎn)換的方式。但是更多的情況下,是由JavaScript自動轉(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),對象類型 (Object)。當(dāng)然Object有可以細(xì)分出 Array , Date , RegExp等等對象。

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

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

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

自動轉(zhuǎn)換

什么時候會發(fā)生自動轉(zhuǎn)換?

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

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

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

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

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

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

+

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

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

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

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

> 、>= 、< 、<= 

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

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

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

== 、 != 

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

  • 一個值是 undefined,一個值是null,則相等
  • 一個值是數(shù)字,一個值是字符串,則字符串轉(zhuǎn)換為數(shù)字進(jìn)行比較
  • truefalse 會分別轉(zhuǎn)換為 10 
  • 一個值是字符串或者數(shù)字,另一個是對象,對象轉(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ù)字

對象包裝

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

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

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

 因為在x需要使用方法的時候,JavaScript會通過調(diào)用 new Number(x) 的方式將它暫時轉(zhuǎn)換為對象,它繼承了Number對象的方法,所以就可以調(diào)用toString了。同樣的還有字符串、布爾值,也是通過各種的構(gòu)造函數(shù)進(jìn)行轉(zhuǎn)換。這也是為什么undefinednull,不可以使用toString的原因,因為它們沒有構(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

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

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

any -> boolean

在其他類型的值轉(zhuǎn)換為 boolean 時,只有這幾個會轉(zhuǎn)換為 false ,其他都是 trueundefinednull 、 ""0 、-0 、NaN

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

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

// 此時是一個boolean對象,而不是原始值,所以是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ù)字,開始和結(jié)尾的空格都可以忽略。不符合的字符串會返回NaN。

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

備注:這里的規(guī)則是自動轉(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.對象 -> number

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

+new Date()  //  1529483712712  date對象的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

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

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

2.object -> string 

和對象轉(zhuǎn)化為數(shù)字類似,不過是先調(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 (中國標(biāo)準(zhǔn)時間)"

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

總結(jié)

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

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

相關(guān)文章

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

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

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

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

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

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

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

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

    這一章詳細(xì)介紹的表單錯誤提示的方法比那種大多數(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ù)及常見的操作,講解的十分詳細(xì),這里推薦給大家
    2014-11-11
  • 最新評論