iT邦幫忙

1

【You Don't Know JS: Types & Grammar】Chapter 4-1 筆記

WM 2019-02-24 22:14:18931 瀏覽

轉換值

將一個值從某個型別轉換至另一個型別的動作,叫做「型別轉換(type casting)」。

因為值的使用規則而被迫轉型的,叫做「強制轉型(coercion)」。

JS強制轉型(coercion)的結果永遠都會是純量的基型值

明確的強制轉型:能夠從程式碼看出型別轉換動作是刻意進行的。

隱含的強制轉型:型別轉換因其他作業而產生較不明顯的副作用。

https://ithelp.ithome.com.tw/upload/images/20190224/20112573JEs3X1v4me.jpg

執行b = a + "",由於+的運算子,其中一個運算元是string的話,那這個運算式就會執行string的串接動作,而(隱藏)的副作用,就是會將42(number)轉換成"42"(string)

至於c = String( a ),則是很明顯地將a的值明確地換成string

以上2者都可以達到相同的效果:42(number)轉換成"42"(string)

如果你很清楚執行b = a + ""的結果,那這個執行對你來說,是「明確」的;但不清楚c = String( a )的結果,這個執行則算是「隱含」的。

要記住的一點是,我們撰寫的程式碼,很少是給自己看的。就算已經是專家等級了,但還是得考慮到團隊成員的程度,對他們來說,你的「明確」與「隱含」是否是他們能理解的呢?

ToString

將任何非string值強制轉型成string表示值。

基型值的轉型:null=>"null"undefined=>"undefined"true=>"true"

如果物件本身擁有自己的toString( )方法,而這個物件被當作string使用,那它的toString( )就會被自動呼叫。

array的toString( )結果:
https://ithelp.ithome.com.tw/upload/images/20190224/20112573jzRvDTTdyO.jpg
輸出string,每個值都以" , "隔開。

ToNumber

如果有任何非number值被當作number值來使用,就會進行轉換,例如數學運算。

基型值的轉型:tru1=>1undefined=>NaN、但是null=>0

object和array會先轉成他們的基型等效值,如若不是一個number值,會再次轉型為number值。

再轉型之前,JS會先確認目標值是否有valueOf( )方法,若有且回傳基型值的話,那個值就會被用於強制轉型;如果沒有valueOf( )方法,會使用toString( )方法(如果有的話)。

如果以上2種執行都無法提供基型值的話,就會擲出TypeError。

ToBoolean

在其他程式語言中,1與0分別代表true與false,但在JS中number就是number,boolean就是boolean。可以把1強制轉型成true,0強制轉型成false(反之亦然),但實際上,他們並不相同。
1並不等於true,0也不等於false。

Falsy值

JS所有的值可以被分為2種:被強制轉型為boolean型別後,不是true就是false。

會被稱為「falsy(假值的)」的值:

  • undefined
  • null
  • false
  • +0、-0、NaN
  • " "

以上的值,如果轉型成boolean會成為flase。

如果某個值不在這清單上,那已較合乎邏輯的想法,我們可以判定它就在另一個清單「truthy」上。

Truthy值

https://ithelp.ithome.com.tw/upload/images/20190224/201125735SGWSyYX4J.jpg

d的結果為true。請注意,以上的值雖然乍看之下會轉為false,但實際上,它們的型別都是string,既然如此,結果當然為true。

https://ithelp.ithome.com.tw/upload/images/20190224/20112573WoIZq0HNJt.jpg

d的結果仍為true。切記,只要是沒在falsy清單的值,都為truthy值。

truthy與flasy的重要性在於,一個值轉型成boolean時,會有怎樣的行為。

明確轉型:Strings <--> Numbers

直接看範例:
https://ithelp.ithome.com.tw/upload/images/20190224/20112573uyLdnkkSaj.jpg
String( )方法會把任何值強制轉型成string,Number( )方法則是會把任何值強制轉型成number。

以上的方式之所以稱為「明確轉型」,是因為可以從程式碼很明顯的看出執行作業的結果。

除了上述的方式之外,也有其他方式能進行「明確轉型」:
https://ithelp.ithome.com.tw/upload/images/20190224/20112573LSgZKIYM2o.jpg

執行a.toString( ),從表面看來,toString( )是執行了「明確轉型」,但這裡有個「隱含轉型」的存在。toString( )是個方法,所以無法用在像是42這種基型值上。JS會自動地把42「封裝」在一個物件包裹器(object wrapper)之中,如此一來,便具有object的行為了,就能呼叫toString( )

至於+c,這個看起來很特別的運算式,只有單一運算元的運算子,不會執行數學運算或string的串接。+運算子會明確地把它的運算元轉型成number值。

https://ithelp.ithome.com.tw/upload/images/20190224/20112573RwRV9HHMka.jpg
-運算子也會像+一樣轉型,但它會反轉數值的正負號。且我們不能把2個相鄰的符號放在一起(--),這樣會被解讀為遞減運算子,應該要在中間加上空格,- -"3.14"

https://ithelp.ithome.com.tw/upload/images/20190224/20112573fQP79L14Wz.jpg

如果會與其他運算子緊密相鄰,應該就要避免使用單一運算子的方式來進行強制轉換,以免造成混淆。

日期轉數字

單一+運算子的另一個用途是將Date object強制轉型成number,結果會是那個日期時間值的unix時間戳(從1970年1月1日 00:00:00 UTC 開始,所經過的毫秒數)。

取得當下的時間戳:
https://ithelp.ithome.com.tw/upload/images/20190224/20112573Vw05mkommg.jpg

有2種非強制轉型的方式:
https://ithelp.ithome.com.tw/upload/images/20190224/201125737WnG7ytJZX.jpg
以及ES5新增的,建議使用
https://ithelp.ithome.com.tw/upload/images/20190224/20112573A8y7E8uxXs.jpg

明確地:剖析數值字串

將一個string的內容剖析出number的動作,可以達成類似將string強制轉換成number的效果,但這種執行與之前討論的string轉型成number還是有所差異。
https://ithelp.ithome.com.tw/upload/images/20190224/20112573BduRfLTuoa.jpg

剖析數值的動作能夠接受非數值字元,從左至右剖析,遇到非數值字元便會停止,輸出剖析成功的數值。

強制轉型無法接受任何非數值字元,轉型會失敗,產生NaN。

如果對於剖析的對象並無要求是否全部為數值,可以使用parseInt( ),但若只能接受數字,譬如"42px"不該視為數字的話,那就使用強制轉型。

parseInt( )只能用於string值。如果傳入一個非string值,該值會先被強制轉型為string,這是一種隱含地強制轉型,這是不好的,請避免這種行為。

明確地:* --> Boolean

使用Boolean( )進行強制轉型:
結果為true
https://ithelp.ithome.com.tw/upload/images/20190224/20112573w2uPbWDFyV.jpg

結果為false
https://ithelp.ithome.com.tw/upload/images/20190224/20112573j6z647zhfe.jpg

雖然Boolean( )可以明確地轉型,但並不普遍。

如同+運算子一樣,!也會強制地將某個值轉型成反向的Boolean值,因此我們會使用!!雙否定運算子再做一次反向。

https://ithelp.ithome.com.tw/upload/images/20190224/20112573q29DznyRXQ.jpg

if(...)敘述式,會強制將值轉換為boolean。

https://ithelp.ithome.com.tw/upload/images/20190224/20112573poccwCehPg.jpg

上面為三元運算子(ternary operator),會依據a的boolean值,判斷指定true或false給b。

表面看起來是明確地強制轉換,但實際上,a運算式會隱含地強制轉型成boolean,才能進行判斷。

就明確轉型來說,Boolean(a)!!a都是比較好的選擇。

參考來源:
https://ithelp.ithome.com.tw/upload/images/20190221/201125739FY75WdXxA.jpg

此為You Don't Know JS系列的筆記。


尚未有邦友留言

立即登入留言