iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 9
0
Modern Web

跟著 YDKJS 作者 Kyle Simpson 打造全新 JavaScript Mindset系列 第 9

[day08] YDKJS (Coercion:spec) : 來讀 Spec.  ToString(), ToNumber() , ToBoolean()

  • 分享至 

  • xImage
  •  

Coercion

中文有人用:型別轉換、強制轉型

ToString ES2018 7.1.12

ES2019 可能還會有微調。 但還沒出,所以這張是最新的。

es5.1 中文版

這張表是 ES5.1 ,僅供參考

  • 一般來說,可以想像成直接轉字串
  • 負數零負號會消失

如果是一個 top level Object ,hint 是 "string"

  • 會先轉字串(toString() ),如果失敗則嘗試轉數字( valueOf()

  • 如果是 Array 則直接拿掉中括號 [ ]
  • 如果字串內是 nulls , undefine 變成空字串,非常奇怪!
  • 可能是因為 JS Array 是 稀疏陣列(Sparse Array),然後 null , undefine 常用來表示 空值 Reference 有關 Array 的值: types & grammar/ch2.md
    裡面提及,任何時候,避免刻意使用 稀疏陣列
  • Kyle Simpson 認為,toString() 應該不要拿掉 中括號 [ ] ,但是 spec 這樣定義,只好用到的時候要非常小心
  • "Number" 轉換建議轉換純整數,如果不是純整數會有很多 邊際狀況(Corner Cases)

  • 為什麼世界上有人覺得,object 不用拿掉 {} ,然後 Array 要 WTA ???
  • 有時候,取用 Internal [[Class]] 並不是那麼有幫助,可以考慮以下例子:
    Object.prototype.toString.call( [1,2,3] ); // "[object Array]"
    更多詳細回傳可以參考 原書
  • 某些用例中,可以增加 getter override toString(),回傳 JSON-stringify 後的結果,這會比回傳 [objects Objects] 更有幫助,如範例第三行。
    註:這屬於 meta programming 的技巧。

ToNumber ES2018 7.1.3

Symbol : Throw a TypeError exception.

這張表是 ES5.1 ,僅供參考

  • '' 空字串變成 0 : Kyle Simpson 認為最奇怪的部分。空字串應該要為 NaN(Invalid number),因為空字串也不是 Number , 變成 0 代表空字串是 Number (WTA????)
  • '-0' 字串,很神奇的會保留負號成為 -0

  • null 變成 0 , undefined 又變回 NaN (WTA????????) ,Kyle Simpson 認為兩個應該都要為 0 或是乾脆都要 NaN 比較合理。
  • 作者認為 false / true 應該要是 NaN (符合 coercion,避免邊際狀況) ,但基於歷史原因 false =>0 / true => 1 , 也只能接受,然後記住更多邊際狀況。

對 top-level object 使用 ToNumber()

  • valueOf 的 hint 是 ToNumber() ,不是直接使用。
  • valueOf : 如果你沒有改寫 return , default 回傳 this
    但基本上這時候 this 不會剛好是 primitive,所以 non-primitive 會使用 ToPrimitive 再執行一次 abstract-operations 演算法

  • 從結果來看,有時候會像是執行 toString()

這邊我一度以為可以在瀏覽器上直接使用 valueOf() ,但事實上不是。
valueOf() 這個基礎函式很容易被改寫,所以通常要看怎麼呼叫它。


這是 spec.

順便附上 MDN - valueOf

舉個例子

  • 複習: array ToPrimitive() 會去掉[]

但是注意!!

  • 這時候 null , undefined 又都是 0 !!! WTA !!!??
  1. Array(toplevel-object) => valueOf()回傳: this(value)
  2. [null] or [undefined] 實際上是執行ToString()
  3. 兩個都變成"" (空字串) ,但此時還不是 number type
  4. 空字串 toNumber() 變成 0 // 之前有提過空字串轉數字 toNumber() 不應該可以變成 0
  • 空 array 下場也是一樣 , toString() 也會變成空字串 ,然後型別不是數字還要轉 toNumber() 變成 0

  • 物件好很多,因為先轉字串會變成 [object Object] , 這個 [object Object] 字串轉數字會變成 NaN
  • 當然也可以用前面提到 meta programming 的技巧 改寫它。

Toboolean ES2018 7.1.2

Toboolean 是單純查表!! 不是演算法不會遞迴 ToPrimitive()

  • Toboolean('') // 空字串
    因為 空字串 不在 falsy表格 裡面 => truthy ,return True
  • Toboolean([]) // 空array
    因為 空 array 不在falsy表格 裡面 => truthy ,return True

反正不是上述條列的 Falsy , 其他全是 Truthy

休息喘口氣

這邊章節文字不多,但是非常基礎也非常容易混淆。
後面會進入綜合的 Coercion 型別轉換,但是基礎還是這章。

Reference:


上一篇
[day07] YDKJS (Type/Coercion) : 來讀 Abstract Operations Spec. : ToPrimitive()
下一篇
[day09] YDKJS (Coercion:spec) : Coercion 型別轉換 ? Boxing Wrappers ?
系列文
跟著 YDKJS 作者 Kyle Simpson 打造全新 JavaScript Mindset31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言