iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 11
0
Modern Web

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

[day10] YDKJS (Coercion) : 如何決定何時使用「顯性」或是「隱性」的型別轉換?

  • 分享至 

  • xImage
  •  

昨天仔細思考之後,決定不寫了。

感謝大家

誒,不是,先別上一頁!!容我解釋⋯⋯

目前想法是,大幅度稀釋文章資訊濃度。
前面幾天寫法包含

  1. Kyle Simpson 寫 YDKJS 真正的理解

通常會看到黑底藍字的圖片。
有時候覺得圖片丟太多就打字 + 翻譯

  1. ECMAScript® 2019 Language Specification

有時候還包含中文翻譯

  1. YDKJS 原文引用、MDN 引用

三種主題的混雜,造成一篇文章,如果沒有三個部分都看,其實不懂的人還是不懂。
也就是懂的人不用看已經懂了。

這好像也偏離想寫東西的原意,希望透過分享讓更多人知道 YDKJS。

所以 ECMAScript® 2019 Language SpecificationYDKJS 原文引用、MDN 引用 會暫時不寫,

之後的文章主要會以 Kyle Simpson 的理解 配合 我自己的理解,
然後 Specification 、 YDKJS 原文引用、MDN 引用 都以附註補上。
希望能讓文章更容易理解。


JavaScript Type Conversion Corner Cases

JavaScript 型別轉換的邊際例子

每個語言都有 Corner Cases,所以每一次新功能要更新 Spec. 都會比較久,因為要確定 Spec. 是Authority 且沒有含糊不清,勢必要好好處理 Corner Cases。
但是認為只有 JavaScript 有 Corner Cases。這樣不合理。

延伸閱讀:

  1. 之前提到的 Bigint
  2. 未來的新功能 Optional chaining

Cases about Corner Cases

事實上前面都有提過,
這些 Corner Cases 在最開始提到型別轉換就有說 Kyle Simpson 認為這樣設計不好,後文會提到,因為除了 Boolean 只做查表,其他型別都會不斷遞迴型別轉換直到 Error 或是成功

Number

比如 Number 的最後只會是

  1. 數字 (空字串、 Null 都會是 0)
  2. NaN (如果前一次 ToPrimitive() 是 非空字串,則會變成 NaN)

Number

然後只要是數字,都會出現連續 Coercion

Kyle Simpson 很真的很討厭空字串變成 0 , 不是 NaN

這邊提一下另一個 Kyle Simpson 很討厭 的東西: Boolean 可以變數字

如果是 NaN 一樣可以避免,但不是 XDD

1 < 2 < 3;  // true 
3 > 2 > 1;  // false ??

看 line 9 , line 19


String

String 的 top level object 內容會連續型別轉換,且 Array 和 Object 的轉換不一樣,

  1. Array 會先去掉 [],但是 空字串條件很多 (見下圖)
  2. Object 會轉換成無意義的 [object Object]

Array

Object

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

如果 JavaScript 的機制避免不了 Coercion , 你應該透過寫非常直白的 code 避免誤會

而不是把所有 JavaScript 的 Coercion 當作不存在,來避免遇到這些誤會。

寫 code 的時候,尤其是寫 JavaScript code,要很小心管理型別

考慮以下方法:

  1. 你寫一個 function ,那就只讓那個 function 處理 Number
  2. 如果 function 可能會有 string ,就拉出來另外寫一個限縮好只接受 string 的 function。
  3. 如果你能夠處理 接受 string, Number 的所有 Corner Cases , 就可以化簡成一個 function

如果你每次寫都不能確定型別,那其實是你程式能力的問題,或是你不夠理解你的 Code。
上述問題其實寫 TypeScript 也會發生,如果能用 多型(Polymorphism)其實你也知道型別了。

Ref: TypeScript 的 union type

你不瞭解的 code 你就不會信任,反之你不信任的 code 代表你不瞭解。

[day02] 誰是 Kyle Simpson ? Code is for ... ? (下)

所以,別人說 JavaScript 型別系統 是古怪設計的時候,
Kyle Simpson 認為 JavaScript 型別系統才是真正讓大家都寫 JavaScript 的原因。

那 JavaScript 對 Junior developers 不是很不友善嗎?

Kyle Simpson 認為,身為 Senior , 你可以用 Code Review, pair programming,或是更好的工具來提升 Junior developer 以及保護 Code base 兩方面。
而不是只是說說不友善,然後嘲笑 Junior 。

這個問題其實是提問者自己的問題,今天把語言換成不是 JavaScript 也一樣會發生。

應該思考,寫 code 是為什麼。

參考
[day01] 誰是 Kyle Simpson ? Code is for ... ? (上)
[day02] 誰是 Kyle Simpson ? Code is for ... ? (下)

我自己之前整理的前端一週年離職心得,其實也有提到保護 Code base 這個部分。

前端一週年離職心得

Code Comments

這邊 Kyle Simpson 也提倡 code comments,但是要為了 communication 而寫 comments。
舉例來說,
i++ 不要寫 這邊 i 會加 1
如果要 communication ,應該寫 i 的狀態,或是 為什麼會、如何導致 i 要 +1 。
當然這邊只是舉例,很多時候的 i++code can explain itself

Implicit != Magic , Implicit != Bad

有一種寫 code 的風格叫做 functional programming , 大量使用 Abstraction 。
所以 Kyle Simpson 說 JavaScript 很適合 functional programming ,而不是物件導向如 Java , C++ 的寫法。

什麼是 Implicit :Abstracted ?

比如之前提到的 Boxing,這就非常實用且不用特意在意細節。

或是這個例子:

其實不用寫上面的語法,雖然很直白,但這時候隱藏細節並不會影響別人了解你的 Code 。

line 8 ,比較的時候也會 Coercion (在確認其中一邊有數字的條件之下),
這也是一種隱藏細節的抽象。

如何判斷型別或是 Coercion,什麼時候要隱藏細節,什麼時候要寫得非常明顯?

如果能確保別人可以讀懂,你就可以用 Implicit 的寫法來抽象細節,
否則能寫明白就寫明白。


Kyle Simpson 的準則。
可以拿 人類理解 code 當作核心去思考寫 code 的意義。


上一篇
[day09] YDKJS (Coercion:spec) : Coercion 型別轉換 ? Boxing Wrappers ?
下一篇
[day11] YDKJS (Equality) : 一般相等 == 比較「值」 , 嚴格相等 === 比較 「型別和值」是錯的?
系列文
跟著 YDKJS 作者 Kyle Simpson 打造全新 JavaScript Mindset31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
tsuifei
iT邦新手 4 級 ‧ 2019-09-26 08:39:53

休淡幾勒~千萬別停~
你的文章真的很充實,雖然無法一時吸收,但覺得是口袋名單。
加油~

Ashe Li iT邦新手 5 級 ‧ 2019-09-26 23:14:30 檢舉

好像會讓人誤會 XD

ECMAScript® 2019 Language SpecificationYDKJS 原文引用、MDN 引用 會暫時不寫,
後面會用 Reference 的補充方式來附註。

我自己也有回去看之前的文章,
也覺得其實不太容易吸收,文筆還需要加強 QQ

我要留言

立即登入留言