昨天介紹了JavaScript有兩個型別,分別是:Primitive type 跟 objects。
今天我們先來認識 Primitive type。
原始資料型別(Primitive Type)是程式語言中的基本型別,它們是不可變(immutable)且直接存儲在記憶體中的數值。這些型別在記憶體中佔用固定大小,並通常是比較簡單的數值,用於儲存單一值。
接下來我們就針對這7項來做一個簡單的介紹:
在JavaScript中,不管是帶整數或是有小數點,所有數字都是單純的數字類型。
另外還有幾種特殊的數字:Infinity
、-Infinity
、NaN
。
Infinity
是指數學上的無限大(正數/0)
Infinity
是指數學上的負無限大(負數/0)
NaN
在 JavaScript 當中是個有趣的存在,就字面上來說,它不是個數字(Not a number),但你若用 typeof
運算子來判斷型態,它又會告訴你這是個 number
。
typeof(NaN);// "number"
因此搞得我有點頭痛,也不是很理解。
在網路上找資料時,有看到一些文章引用《You Don't Know JS》這本書,在書裡作者有做了一段解釋:
It would be much more accurate to think of NaN as being “invalid number,” “failed number,” or even “bad number,” than to think of it as “not a number.”
NaN is a kind of “sentinel value” (an otherwise normal value that’s assigned a special meaning) that represents a special kind of error condition within the number set. The error condition is, in essence: “I tried to perform a mathematic operation but failed, so here’s the failed number result instead.”
NaN最好被理解為“無效數字”、“失敗的數字”或甚至“錯誤數字”,而不是“非數字”。
NaN是一種“特殊值”(一個被賦予特殊含義的正常值),代表數字集合中的一種特殊錯誤狀態。這個錯誤狀態實際上是:“我嘗試進行一個數學運算,但失敗了,所以這裡是失敗的結果。”
我自己的解讀是:NaN
是一個Number類型的數值,但這個值無法用真實的數字表示。
既然知道什麼是NaN
了,那要如何判斷呢?
這邊我們要先清楚知道一件事情,NaN
與任何數字作數學運算,結果都是 NaN
。 也就是說, NaN
並不等於任何的數字,甚至是自己。
在傳統上會使用isNaN()
,但現在大家都會使用Number.isNaN()
,會這樣改變是因為isNaN()
一直存在誤判的問題,我們來看下面的例子就更清楚了:
isNaN({}) //true
isNaN('hello') //true
我們剛剛確定了NaN
是一個Number類型的數值,因此當我們判斷 object 跟 string 時,照理講應該是要為 false
才對,但上面卻顯示為 true
。
會造成這樣的原因主要是因為isNaN
會先把()裡的值轉型成數字,如果不能轉成數字,這個值就是NaN
了。
isNaN({}) // 會先將()內的{}轉為數字,得到 NaN
// 因此會變成這樣子
isNaN(NaN) // 檢查是否為 NaN,得到 true
為了解決先轉型做數字而導致誤判的這個問題,ES6提出了使用Number.isNaN()
的建議。
Number.isNaN()
不會事先把()裡的值轉為數字,而是判斷該值是否一個數字,因此避免了剛剛的錯誤。
另外,由於JavaScript 的 number 實作是基於「IEEE 754」二進位浮點數算術標準。
因此當我們看到:
0.1 + 0.2 === 0.3 //false
不要感到訝異,這不是瀏覽器發生錯誤,而是十進位的小數無法完美的用二進位的方式表示,只能用無限循環的位數來趨近於十進位的小數,因此才會出現這樣的結果。
為了避免這個誤差問題,最直接的方法是把數字轉為整數才去作其他處理。目前我所知道的大多數人都比較推薦用JS函式庫,例如number precision、math.js等等去作處理。
JavaScript並沒有字元(char)的概念,只有字串。
字串會用一組單引號(’ ’)或是雙引號(” “)包夾住,兩者不可混用。
let str1 = '這是一個字串';
let str2 = "這也是一個字串";
let str3 = 'Let's go!'; // error
//改成以下的方式就可以
let str3 = "Let's go!";
let str3 = 'Let\'s go!'; // \n或者\是跳脫字元
或是也可以使用ES6後出來的Template String:
使用 反引號(``) 來插入一段字串,並且可以使用 ${}
來加入變數或函式,如下:
let count = 2
let price = 150
console.log(`購物車金額總共是${count * price}元`);
只會回傳兩種值:True
或 False
,大量運用在邏輯判斷中。
之後會提到 Coercion(強制轉換)時,在boolean時會提到兩個名詞:falsy
與truthy
。
他的概念其實很簡單,只要記的所有的物件都是 Truthy
, 只有 空字串, 數字0, NaN, false, undefined和 null 會是 Falsy
, 其餘的都是 Truthy
。
if (false) {
console.log("This won't be printed"); // 不會執行,因為 false 是 falsy 值
}
if (0) {
console.log("This won't be printed"); // 不會執行,因為 0 是 falsy 值
}
if ('') {
console.log("This won't be printed"); // 不會執行,因為空字串是 falsy 值
}
if (null) {
console.log("This won't be printed"); // 不會執行,因為 null 是 falsy 值
}
if (undefined) {
console.log("This won't be printed"); // 不會執行,因為 undefined 是 falsy 值
}
if (NaN) {
console.log("This won't be printed"); // 不會執行,因為 NaN 是 falsy 值
}
if (true) {
console.log("This will be printed"); // 會執行,因為 true 是 truthy 值
}
if (42) {
console.log("This will be printed"); // 會執行,因為 42 是 truthy 值
}
if ('hello') {
console.log("This will be printed"); // 會執行,因為非空字串是 truthy 值
}
null
:我定義了一個新的變數,並賦值 null
給這個變數。
const color = null; // 宣告 color 並赋值 null
console.log(color); // null
undefined
:我定義了一個新的變數,卻沒有賦值給它,它的值就會是 undefined
;或者表示object 的屬性不存在
let x; // 宣告 x,但未赋值
console.log(x); // undefined
const person = { name: "John", age: 30 };
console.log(person.address); // 不存在的属性,輸出 undefined
Symbol 是透過Symbol()
生成的。
let s = Symbol();
typeof s
// "symbol"
由於它是 Primitive type,表示獨一無二的值。建立它我們不需要使用 new 這個指令。
Symbol()
可以接受一個字串作為参數,表示對 Symbol 的描述,方便之後做區分。
let s1 = Symbol('foo');
let s2 = Symbol('bar');
s1 // Symbol(foo)
s2 // Symbol(bar)
s1.toString() // "Symbol(foo)"
s2.toString() // "Symbol(bar)"
因為沒有用到過所以就先簡略介紹一下,詳細內容可以到 這裡 了解。
從ES2020開始被引入,對數學、金融、科學來說是很重要的,因為當number因為當number大於某範圍會有精確度問題,故會將值當作string處理,但BigInt是可以表示為numeric values。
因為沒有用到過所以就先簡略介紹一下
以上就是對於Primitive type的簡單介紹,明天就來把資料型別給全部結束!