JS中類型轉(zhuǎn)換的示例分析-創(chuàng)新互聯(lián)

這篇文章將為大家詳細(xì)講解有關(guān)JS中類型轉(zhuǎn)換的示例分析,小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,希望大家閱讀完這篇文章后可以有所收獲。

成都創(chuàng)新互聯(lián)于2013年成立,先為田林等服務(wù)建站,田林等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為田林企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問(wèn)題。

前言

類型轉(zhuǎn)換是將值從一種類型轉(zhuǎn)換為另一種類型的過(guò)程(比如字符串轉(zhuǎn)數(shù)字,對(duì)象轉(zhuǎn)布爾值等)。任何類型不論是原始類型還是對(duì)象類型都可以進(jìn)行類型轉(zhuǎn)換,JavaScript 的原始類型有:number, string, boolean, null, undefined, Symbol。

本文將通過(guò) 17 道題目來(lái)深入的了解 JS 中的類型轉(zhuǎn)換,通過(guò)閱讀本文之后,你將能自信的回答出下面題目的答案,并且能夠理解背后的原理。在文章的最后,我講寫出答案并解釋。在看答案之前,你可以把答案寫下來(lái),最后再對(duì)照一下,便于找出理解有誤的地方。

true + false
12 / "6"
"number" + 15 + 3
15 + 3 + "number"
[1] > null
"foo" + + "bar"
"true" == true
false == "false"
null == ""
!!"false" == !!"true"
["x"] == "x"
[] + null + 1
[1,2,3] == [1,2,3]
{} + [] + {} + [1]
! + [] + [] + ![]
new Date(0) - 0
new Date(0) + 0

類似于上面的這些問(wèn)題大概率也會(huì)在 JS 面試中被問(wèn)到, 所以繼續(xù)往下讀。

隱式 vs 顯式類型轉(zhuǎn)換

類型轉(zhuǎn)換可以分為隱式類型轉(zhuǎn)換和顯式類型轉(zhuǎn)換。

當(dāng)開發(fā)人員通過(guò)編寫適當(dāng)?shù)拇a(如Number(value))用于在類型之間進(jìn)行轉(zhuǎn)換時(shí),就稱為顯式類型強(qiáng)制轉(zhuǎn)換(或強(qiáng)制類型轉(zhuǎn)換)。

然而 JavaScript 是弱類型語(yǔ)言,在某些操作下,值可以在兩種類型之間自動(dòng)的轉(zhuǎn)換,這叫做隱式類型轉(zhuǎn)換。在對(duì)不同類型的值使用運(yùn)算符時(shí)通常會(huì)發(fā)生隱式類型轉(zhuǎn)換。比如 1 == null, 2 / "5", null + new Date() 。當(dāng)值被 if 語(yǔ)句包裹時(shí)也有可能發(fā)生,比如 if(value) {} 會(huì)將 value 轉(zhuǎn)換為 boolean類型。

嚴(yán)格相等運(yùn)算符(===)不會(huì)觸發(fā)類型隱式轉(zhuǎn)換,所以它可以用來(lái)比較值和類型是否都相等。

隱式類型轉(zhuǎn)換是一把雙刃劍,使用它雖然可以寫更少的代碼但有時(shí)候會(huì)出現(xiàn)難以被發(fā)現(xiàn)的bug。

三種類型轉(zhuǎn)換

我們需要知道的第一個(gè)規(guī)則是:在 JS 中只有 3 種類型的轉(zhuǎn)換

  • to string

  • to boolean

  • to number

第二,類型轉(zhuǎn)換的邏輯在原始類型和對(duì)象類型上是不同的,但是他們都只會(huì)轉(zhuǎn)換成上面 3 種類型之一。

我們首先分析一下原始類型轉(zhuǎn)換。

String 類型轉(zhuǎn)換

String() 方法可以用來(lái)顯式將值轉(zhuǎn)為字符串,隱式轉(zhuǎn)換通常在有 + 運(yùn)算符并且有一個(gè)操作數(shù)是 string 類型時(shí)被觸發(fā),如:

String(123) // 顯式類型轉(zhuǎn)換

123 + '' // 隱式類型轉(zhuǎn)換

所有原始類型轉(zhuǎn) String 類型

String(123) // '123'
String(-12.3) // '-12.3'
String(null) // 'null'
String(undefined) // 'undefined'
String(true) // 'true'

Symbol 類型轉(zhuǎn) String 類型是比較嚴(yán)格的,它只能被顯式的轉(zhuǎn)換

String(Symbol('symbol')) // 'Symbol(symbol)'

'' + Symbol('symbol') // TypeError is thrown

Boolean 類型轉(zhuǎn)換

Boolean() 方法可以用來(lái)顯式將值轉(zhuǎn)換成 boolean 型。

隱式類型轉(zhuǎn)換通常在邏輯判斷或者有邏輯運(yùn)算符時(shí)被觸發(fā)(|| && !)。

Boolean(2) // 顯示類型轉(zhuǎn)換
if(2) {} // 邏輯判斷觸發(fā)隱式類型轉(zhuǎn)換
!!2  // 邏輯運(yùn)算符觸發(fā)隱式類型轉(zhuǎn)換
2 || 'hello' // 邏輯運(yùn)算符觸發(fā)隱式類型轉(zhuǎn)換

注意: 邏輯運(yùn)算符(比如 || 和 &&)是在內(nèi)部做了 boolean 類型轉(zhuǎn)換,但實(shí)際上返回的是原始操作數(shù)的值,即使他們都不是 boolean 類型。

// 返回 number 類型 123,而不是 boolean 型 true
// 'hello' 和 '123' 仍然在內(nèi)部會(huì)轉(zhuǎn)換成 boolean 型來(lái)計(jì)算表達(dá)式
let x = 'hello' && 123 // x === 123

boolean 類型轉(zhuǎn)換只會(huì)有 true 或者 false 兩種結(jié)果。

Boolean('')  // false
Boolean(0)  // false 
Boolean(-0)  // false
Boolean(NaN)  // false
Boolean(null)  // false
Boolean(undefined) // false
Boolean(false) // false

任何不在上面列表中的值都會(huì)轉(zhuǎn)換為 true, 包括 object, function, Array, Date 等,Symbol 類型是真值,空對(duì)象和空數(shù)組也是真值。

Boolean({})  // true
Boolean([])  // true
Boolean(Symbol()) // true
!!Symbol()  // true
Boolean(function() {}) // true

Number 類型轉(zhuǎn)換

和 Boolean()、String() 方法一樣, Number() 方法可以用來(lái)顯式將值轉(zhuǎn)換成 number 類型。
number 的隱式類型轉(zhuǎn)換是比較復(fù)雜的,因?yàn)樗梢栽谙旅娑喾N情況下被觸發(fā)。

  1. 比較操作(>, <, <=, >=)

  2. 按位操作(| & ^ ~)

  3. 算數(shù)操作(- + * / %), 注意,當(dāng) + 操作存在任意的操作數(shù)是 string 類型時(shí),不會(huì)觸發(fā) number 類型的隱式轉(zhuǎn)換

  4. 一 元 + 操作

  5. 非嚴(yán)格相等操作(== 或者 !== ),注意,== 操作兩個(gè)操作數(shù)都是 string 類型時(shí),不會(huì)發(fā)生 number 類型的隱式轉(zhuǎn)換

Number('123') // 顯示類型轉(zhuǎn)換
+ '123'  // 隱式類型轉(zhuǎn)換
123 != "456" // 隱式類型轉(zhuǎn)換
4 > "5" // 隱式類型轉(zhuǎn)換
5 / null // 隱式類型轉(zhuǎn)換
true | 0 // 隱式類型轉(zhuǎn)換

接下來(lái)看一下原始類型顯示轉(zhuǎn)換 number 類型會(huì)發(fā)生什么

Number(null)   // 0
Number(undefined)  // NaN
Number(true)   // 1
Number(false)   // 0
Number(" 12 ")   // 12
Number("-12.34")  // -12.34
Number("\n")   // 0
Number(" 12s ")  // NaN
Number(123)   // 123

當(dāng)將一個(gè)字符串轉(zhuǎn)換為一個(gè)數(shù)字時(shí),引擎首先刪除前尾空格、\n、\t 字符,如果被修剪的字符串不成為一個(gè)有效的數(shù)字,則返回 NaN。如果字符串為空,則返回 0。

Number() 方法對(duì)于 null 和 undefined 的處理是不同的, null 會(huì)轉(zhuǎn)換為 0, undefined 會(huì)轉(zhuǎn)換為 NaN

不管是顯式還是隱式轉(zhuǎn)換都不能將 Symbol 類型轉(zhuǎn)為 number 類型,當(dāng)試圖這樣操作時(shí),會(huì)拋出錯(cuò)誤。

Number(Symbol('my symbol')) // TypeError is thrown
+Symbol('123')   // TypeError is thrown

這里有 2 個(gè)特殊的規(guī)則需要記?。?/p>

1、當(dāng)將 == 應(yīng)用于 null 或 undefined 時(shí),不會(huì)發(fā)生數(shù)值轉(zhuǎn)換。null 只等于 null 或  undefined,不等于其他任何值。

null == 0  // false, null is not converted to 0
null == null  // true
undefined == undefined // true
null == undefined // true
undefined == 0  // false

2、NaN 不等于任何值,包括它自己

NaN === NaN // false

if(value !== value) { console.log('the value is NaN') }

object 類型轉(zhuǎn)換

到這里我們已經(jīng)深入了解了原始類型的轉(zhuǎn)換,接下來(lái)我們來(lái)看一下 object 類型的轉(zhuǎn)換。

當(dāng)涉及到對(duì)象的操作比如:[1] + [2,3],引擎首先會(huì)嘗試將 object 類型轉(zhuǎn)為原始類型,然后在將原始類型轉(zhuǎn)為最終需要的類型,而且仍然只有 3 種類型的轉(zhuǎn)換:number, string, boolean

最簡(jiǎn)單的情況是 boolean 類型的轉(zhuǎn)換,任何非原始類型總是會(huì)轉(zhuǎn)換成 true,無(wú)論對(duì)象或數(shù)組是否為空。

對(duì)象通過(guò)內(nèi)部 [[ToPrimitive]] 方法轉(zhuǎn)換為原始類型,該方法負(fù)責(zé)數(shù)字和字符串轉(zhuǎn)換。

[[ToPrimitive]] 方法接受兩個(gè)參數(shù)一個(gè)輸入值和一個(gè)需要轉(zhuǎn)換的類型(Numer or String)

number 和 string的轉(zhuǎn)換都使用了對(duì)象的兩個(gè)方法: valueOf 和 toString。這兩個(gè)方法都在 Object.prototype 上被聲明,因此可用于任何派生類,比如 Date, Array等。

通常上 [[ToPrimitive]] 算法如下:

  • 如果輸入的值已經(jīng)是原始類型,直接返回這個(gè)值。

  • 輸入的值調(diào)用 toString() 方法,如果結(jié)果是原始類型,則返回。

  • 輸入的值調(diào)用 valueOf() 方法,如果結(jié)果是原始類型,則返回。

  • 如果上面 3 個(gè)步驟之后,轉(zhuǎn)換后的值仍然不是原始類型,則拋出 TypeError 錯(cuò)誤。

number 類型的轉(zhuǎn)換首先會(huì)調(diào)用 valueOf() 方法,如果不是原始值在調(diào)用 toString() 方法。 string 類型的轉(zhuǎn)換則相反。

大多數(shù) JS 內(nèi)置對(duì)象類型的 valueOf() 返回這個(gè)對(duì)象本身,其結(jié)果經(jīng)常被忽略,因?yàn)樗皇且粋€(gè)原始類型。所以大多數(shù)情況下當(dāng) object 需要轉(zhuǎn)換成 number 或 string 類型時(shí)最終都調(diào)用了 toString() 方法。

當(dāng)運(yùn)算符不同時(shí),[[ToPrimitive]] 方法接受的轉(zhuǎn)換類型參數(shù)也不相同。當(dāng)存在 == 或者 + 運(yùn)算符時(shí)一般會(huì)先觸發(fā) number 類型的轉(zhuǎn)換再觸發(fā) string 類型轉(zhuǎn)換。

在 JS 中你可以通過(guò)重寫對(duì)象的 toString 和 valueOf 方法來(lái)修改對(duì)象到原始類型轉(zhuǎn)換的邏輯。

答案解析

接下來(lái)我們按照之前的轉(zhuǎn)換邏輯來(lái)解釋一下每一道題,看一下是否和你的答案一樣。

true + false // 1

'+' 運(yùn)算符會(huì)觸發(fā) number 類型轉(zhuǎn)換對(duì)于 true 和 false

12 / '6' // 2

算數(shù)運(yùn)算符會(huì)把字符串 ‘6' 轉(zhuǎn)為 number 類型

"number" + 15 + 3 // "number153"

'+' 運(yùn)算符按從左到右的順序的執(zhí)行,所以優(yōu)先執(zhí)行 “number” + 15, 把 15 轉(zhuǎn)為 string 類型,得到 “number15” 然后同理執(zhí)行 “number15” + 3

15 + 3 + "number" // "18number"

15 + 3 先執(zhí)行,運(yùn)算符兩邊都是 number 類型 ,不用轉(zhuǎn)換,然后執(zhí)行 18 + “number” 最終得到 “18number”

[1] > null // true

==> '1' > 0
==> 1 > 0
==> true

比較運(yùn)算符 > 執(zhí)行 number 類型隱式轉(zhuǎn)換。

"foo" + + "bar" // "fooNaN"

==> "foo" + (+"bar")
==> "foo" + NaN
==> "fooNaN"

一元 + 運(yùn)算符比二元 + 運(yùn)算符具有更高的優(yōu)先級(jí)。所以 + bar表達(dá)式先求值。一元加號(hào)執(zhí)行字符串“bar” 的 number 類型轉(zhuǎn)換。因?yàn)樽址淮硪粋€(gè)有效的數(shù)字,所以結(jié)果是NaN。在第二步中,計(jì)算表達(dá)式'foo' + NaN。

'true' == true // false

==> NaN == 1
==> false

'false' == false // false

==> NaN == 0
==> false

== 運(yùn)算符執(zhí)行 number 類型轉(zhuǎn)換,'true' 轉(zhuǎn)換為 NaN, boolean 類型 true 轉(zhuǎn)換為 1

null == '' // false

null 不等于任何值除了 null 和 undefined

!!"false" == !!"true" // true

==> true == true
==> true

!! 運(yùn)算符將字符串 'true' 和 'false' 轉(zhuǎn)為 boolean 類型 true, 因?yàn)椴皇强兆址?,然后兩邊都?boolean 型不在執(zhí)行隱式轉(zhuǎn)換操作。

['x'] == 'x' // true

== 運(yùn)算符對(duì)數(shù)組類型執(zhí)行 number 轉(zhuǎn)換,先調(diào)用對(duì)象的 valueOf() 方法,結(jié)果是數(shù)組本身,不是原始類型值,所以執(zhí)行對(duì)象的 toString() 方法,得到字符串 'x'

[] + null + 1 // 'null1'

==> '' + null + 1
==> 'null' + 1
==> 'null1'

'+' 運(yùn)算符執(zhí)行 number 類型轉(zhuǎn)換,先調(diào)用對(duì)象的 valueOf() 方法,結(jié)果是數(shù)組本身,不是原始類型值,所以執(zhí)行對(duì)象的 toString() 方法,得到字符串 '', 接下來(lái)執(zhí)行表達(dá)式 '' + null + 1。

0 || "0" && {} // {}

==> (0 || '0') && {}
==> (false || true) && true
==> true && true
==> true

邏輯運(yùn)算符 || 和 && 將值轉(zhuǎn)為 boolean 型,但是會(huì)返回原始值(不是 boolean)。

[1,2,3] == [1,2,3] // false

當(dāng)運(yùn)算符兩邊類型相同時(shí),不會(huì)執(zhí)行類型轉(zhuǎn)換,兩個(gè)數(shù)組的內(nèi)存地址不一樣,所以返回 false

{} + [] + {} + [1] // '0[object Object]1'

==> +[] + {} + [1]
==> 0 + {} + [1]
==> 0 + '[object Object]' + '1'
==> '0[object Object]1'

所有的操作數(shù)都不是原始類型,所以會(huì)按照從左到右的順序執(zhí)行 number 類型的隱式轉(zhuǎn)換, object 和 array 類型的 valueOf() 方法返回它們本身,所以直接忽略,執(zhí)行 toString() 方法。 這里的技巧是,第一個(gè) {} 不被視為 object,而是塊聲明語(yǔ)句,因此它被忽略。計(jì)算從 +[] 表達(dá)式開始,該表達(dá)式通過(guò)toString()方法轉(zhuǎn)換為空字符串,然后轉(zhuǎn)換為0。

! + [] + [] + ![] // 'truefalse'

==> !(+[]) + [] + (![])
==> !0 + [] + false
==> true + [] + false
==> true + '' + false
==> 'truefalse'

一元運(yùn)算符優(yōu)先執(zhí)行,+[] 轉(zhuǎn)為 number 類型 0,![] 轉(zhuǎn)為 boolean 型 false。

new Date(0) - 0 // 0

==> 0 - 0
==> 0

'-' 運(yùn)算符執(zhí)行 number 類型隱式轉(zhuǎn)換對(duì)于 Date 型的值,Date.valueOf() 返回到毫秒的時(shí)間戳。

new Date(0) + 0

==> 'Thu Jan 01 1970 02:00:00 GMT+0200 (EET)' + 0
==> 'Thu Jan 01 1970 02:00:00 GMT+0200 (EET)0'

'+' 運(yùn)算符觸發(fā)默認(rèn)轉(zhuǎn)換,因此使用 toString() 方法,而不是 valueOf()。

關(guān)于“JS中類型轉(zhuǎn)換的示例分析”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,使各位可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),請(qǐng)把它分享出去讓更多的人看到。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無(wú)理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國(guó)服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡(jiǎn)單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

文章名稱:JS中類型轉(zhuǎn)換的示例分析-創(chuàng)新互聯(lián)
本文鏈接:http://muchs.cn/article44/higee.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)靜態(tài)網(wǎng)站、軟件開發(fā)面包屑導(dǎo)航、商城網(wǎng)站ChatGPT

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

h5響應(yīng)式網(wǎng)站建設(shè)