keywords: type
,array
,object
,function
,typeof
值與型別 ( Value and Type )
JavaScript 裡只有值擁有型別,變數不會有型別,這跟 C# 就很不一樣
JavaScript 有 7 種內建型別:
string、number、boolean、null、undefined、object、symbol ( ES6 新引進的 )使用 typeof 運算子檢視一個值,typeof a 不是在詢問 「a 的型別是什麼」,而是詢問「目前在 a 中的值的型別是什麼」,而回傳的值是上方 7 種型別的 "字串值"
ex:typeof 1 //'number'
typeof 'abc' //'string'
7 種型別最特別的是
null
先看一下typeof null //'object'
0.o? hello?
這是存在已久的 bug ,但永遠都不會被修補,因為有太多 Web 的程式碼仰賴這個 bug。
程式其實也會有錯就跟人都有缺點一樣變數可能以數個不同方式達到未定義 ( undefined ) 值的狀態,包含了沒有回傳值的函式
let a; let b = undefined; typeof a //'undefined' typeof b //'undefined' function abc() { return 1 } function bbb() { 1 + 2 } typeof abc() // 'number' typeof bbb() // 'undefined' typeof abc // 'function' typeof bbb // 'function'
物件 ( Object )
- Object 型別代表了一種複合值 ( compound value ),也是 JavaScript 最實用的型別之一,可以對它設定一些特性 ( properties 具名的位置 )
const obj ={ a: 42, b: 'hi', 'c c c': true } a、b、'c c c' 就是 properties
- 物件特性可以透過點記號法 ( dot notation ex. obj.a ),或是方括號記號法 ( bracket notation ex. obj['a'] )來存取。
- 點記號法比較短,也比較容易閱讀,盡可能優先選用它。
- 但有兩種狀況要使用方括號記號法:
- 特性名稱中有特殊的字元,obj['c c c']
obj.a // 42 obj['c c c'] // true
- 想要動態為特性賦值,(( 最近專案有這樣的需求剛好用上 !
let propertyName = 'c c c'; obj[propertyName] = false; obj // {a: 42, b: "hi", c c c: false}
- 特性名稱中有特殊的字元,obj['c c c']
陣列 ( Array )
陣列是類似列表 list 的物件,也是特化版的 object 型別。
- 同時是以數值化的索引位置來儲存
const arr= [ 'hi everyone', 3, false ] typeof arr // object arr[0]; // 'hi everyone'
JavaScript 當中無法點記號法 ( obj. ) 來參照一個名稱開頭為數字的屬性,而必須括號的表示方式來存取
arr.0 // Uncaught SyntaxError: Unexpected number arr[2] // false
也可以將 JavaScript 陣列的索引用引號包起來(ex:arr['2'] instead of arr[2]),不過這不是必要的,但其實 JavaScript 會透過隱含的 toString,將 arr[2] 當中的 2 強制轉換為字串,像這樣 arr['2']
最好且最自然的是使用陣列處理數值位置的值,使用 object 處理具名特性。
函式 ( Function )
函式與陣列一樣是 object 的子型別
function foo(){
return 42
}
typeof foo() // number
typeof foo // function
等等好像怪怪的 0.o 記得
typeof array 是 object
typeof foo 卻是 function
什麼意思!?
ECMAScript 11.4.3 有一張表格,其中
Type of val | Result |
---|---|
Object ( native and does not implement [[Call]] ) | "object" |
Object ( native or host and does implement [[Call]] ) | "function" |
意思是:function 是 object 但如果有實作 [[Call]] 的話就回傳 function,我們拿上方的例子
arr.call() // Uncaught TypeError: arr.call is not a function
foo.call() // 42
只是很好奇為什麼需要這麼麻煩特別為有沒有實作 [[Call]] 另外再回傳 function,找到了一篇文章What Is the JavaScript TypeOf Function? How Does It Work? 裡面寫到:
TypeOf function is a quick way to check data to make sure that a script will work.
typeof function 可以檢查是否有資料回傳或知道資料的型別,利於工程師快速處理後續動作
if(typeof foo === 'function'){
switch(typeof foo()){
case 'number':
// 這裡會在這邊 do something..
case 'string':
// do something..
default:
// do something..
}
}
最後整理一下 JavaScript 定義的型別與 Typeof 回傳的型別:
JavaScript:
- string
- number
- boolean
- null
- undefined
- object
- Symbol ( ES6 新引進的 )
Typeof:
- string
- number
- boolean
- undefined
- object
- function
- Symbol ( ES6 新引進的 )