iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 5
1
Modern Web

【這些年我似是非懂的 Javascript】系列 第 5

【這些年我似是非懂的 Javascript】Day 5 - 飽受爭議的型別

圖片來源

嗨各位你們好,我是 Robin~

之前在 【這些年我不懂的 Javascript】Day 3 - 你一定可以入的了門 #上篇
這篇有提到 JS 沒有支援有型別的變數,
但是有滿多強型別語言的擁護者會說:
JS 不該宣稱擁有型別系統 。
說實話包括我以前也會說 JS 沒有型別系統,
但我覺得每個語言都有它獨有的特色和精神,用別的語言爭論這件事好像沒什麼意思。

如何正確的將值轉換成不同的型別,對於每個型別有他的固定有的行為並且正確地理解它,我相信被最受抨擊的"強制轉型",對你來說可能就不是那麼的可怕。
俗話說的好

知己知彼百戰百勝

(今天不會講"強制轉型",因為我有偷看後面有專門的章節在講xD)

開始我們今天的學習~

內建型別

JS 定義了以下七種內建型別

  • null
  • undefined
  • boolean
  • number
  • string
  • object
  • symbol (ES6 新增的)

除了 null 之外其他型別使用 typeof 都有對應型別的值。
如下範例

typeof null // 'object'
typeof undefined // undefined
typeof true // 'boolean'
typeof 66 // 'number'
typeof "77" // 'string'
typeof {name: "robin"} // 'object'
typeof Symbol() // 'symbol'

每次我看到 null 內心就會出現當兵班長常說的...

又是你! 就你最特別! 標新立異!

就如同我之前所說的,
他是一個萬年臭蟲,
不要奢望他去修他,我們懷念他。

那我該如何透過其他型別來測試他是 null 呢?

const a = null;
(!a && a === "object"); // true

null是唯一一個是基型值卻是 falsy 的 ,然後 typeof 又會回傳 object

還記得前幾篇還有提到 函式
"函式實際上就是物件" 那...
你知道函式原來也可以使用 length 特性嗎? (我也是現在才知道)
但是他不一樣的是他會回傳的是"參數的個數",如下範例

const test = function(arg1, arg2, arg3){
    return
}

test.length // 3

未定義 ( undefined ) vs 未宣告 ( undeclared )

簡單來說,以我簡單不專業的以字面上分析...

  • 未定義 就是宣告了但是沒有給他值。
  • 未宣告 就是沒宣告根本沒這東西。

還是看不懂? 來看看範例

let a;
console.log(a); // undefined
console.log(b); // Uncaught ReferenceError: b is not defined

這感覺是很明顯的差異...
但是使用 typeof 時給我們的答覆卻是不如我們所料...

let a;
typeof a; // undefined
typeof b; // undefined

WTF...

書中寫道,這可能是 typeof 的一種特殊的安全防護機制,而這個安全防護機制是一項實用的特色,假如說你有一個全域變數叫做 DEBUG,假如你想要檢查這個 DEBUG 但不想要被 ReferenceError 拋出例外,那你就可以使用 typeof 的安全防護機制來檢查如以下範例。

// 出大事,拋出例外
if (DEBUG){
    // do something
}

// 使用 typeof 這個安全機制來檢查
if (typeof DEBUG !== "undefined"){
    // do something
}

如果不使用 typeof 這個安全防護就不能知道有沒有被宣告了嗎 Orz?
不!你還可以利用 "所有的全域變數都是全域物件" 這個特性,什麼意思?
還記得你宣告一個物件時當你使用一個沒有的特性他會回你 undefined 而不會被拋出例外,大概就是這個概念。
那在瀏覽器中我們就可以藉由 windows 這個全域物件來檢查,如下範例。

if (windows.DEBUG){
    // do something
}

if (!windows.DEBUG){
    // do something
}

而我個人滿常見還有另一種做法,叫做"依存性注入"這個設計模式,如以下範例。

const test = function(someFunc){
    const balabala = someFunc || function(){
        // do something
    }
    const coolfunc = balabala();
    // ...
}

但是在 ES6 的時代已經可以使用預設參數來取代。

有沒有一種一直在改朝換代的感覺xDD
突然覺得現在學 JS 好幸福,已經可以使用很便捷的方式撰寫。


感覺在寫前面的文章已經把自己對於該名詞都講得差不多了,以至於部分文章內容我不想在重複寫一遍,感覺自己讀起來有點不順(單純指排版),真希望可以一條龍的一次講 (但是我相信他這樣排一定有他的道理XD)。

目前讀下來覺得這本書的筆者都以深入淺出的方式解釋~讚讚!

明天來談談 "" 似乎有很多可以學習呢!

明天見


參考來源:

你所不知道的 JS|導讀,型別與文法 (You Don't Know JS: Up & Going)


上一篇
【這些年我似是非懂的 Javascript】Day 4 - 你一定可以入的了門 #下篇
下一篇
【這些年我似是非懂的 Javascript】Day 6 - 值
系列文
【這些年我似是非懂的 Javascript】34

尚未有邦友留言

立即登入留言