介紹 JavaScript 中的資料型態 (型別),包含布林 (Boolean)、數值 (Number) 和字串 (String),以及轉型的方法。

簡介

型別的種類

在 JavaScript 中有八種主要的型別:

三種基本型別:

  • 布林 (Boolean)
  • 數值 (Number)
  • 字串 (String)

兩種複合的型別:

  • 陣列 (Array)
  • 物件 (Object)

兩種簡單型別:

  • 空值 (null)
  • 未定義 (undefined)

一種特殊型別:

  • 函式 (Function)

動態型別

JavaScript 是一種動態型別語言 (Dynamic typed language),可以不需要特別的宣告,例如:

1
2
var num = 123;
num = '一二三';

不需要特別轉型。JavaScript 具有自動型態轉換的特性,在大多數的時候交由 JavaScript 自動轉型即可。

型別的判斷

可以用 typeof 操作子來取得變數的型別,也可以用 typeof() 類似函式的寫法 (實際上是括號運算子,由於運算子優先序問題,建議使用這個方式):

1
2
3
4
5
6
7
8
9
10
11
console.log(typeof(true));          // boolean
console.log(typeof(123)); // number
console.log(typeof(NaN)); // number
console.log(typeof(Infinity)); // number
console.log(typeof(-Infinity)); // number
console.log(typeof('一二三')); // string
console.log(typeof([])); // object,不是 array
console.log(typeof({})); // object
console.log(typeof(undefined)); // undefined
console.log(typeof(null)); // object,特別注意
console.log(typeof(function(){})); // function

物件類別

布林、數值和字串三種基本型別都有個別對應到一個物件類別,透過該物件類別包裝後,可以進行函式操作,例如字串物件可使用 substr() 等函式。可以透過下面的方式將型別包裝成物件與操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var b = new Boolean(false);
var n = new Number(5566);
var s = new String('friend');

// 包裝後型別為object
console.log(typeof(b)); // object
console.log(typeof(n)); // object
console.log(typeof(s)); // object

// 由於自動轉型,仍然可以比較
console.log(b == false); // true
console.log(n == 5566); // true
console.log(s == 'friend'); // true

console.log(s.substr(3, 3)); // end

實際上使用物件函式並不需要自己手動轉換,JavaScript 會自動處理:

1
2
var s = 'friend';
console.log(s.substr(3, 3)); // end

實務上應該交由 JavaScript 來處理,不建議包裝成物件類別的用法。

布林 (Boolean)

語法

布林的值只有兩種,truefalse,只能是小寫。

1
2
var flag = false;
console.log(flag == false); // true

轉型

基本上 JavaScript 不需要特別去轉型,但如果需要特別轉型也是有辦法,布林可以用以下方法轉型

  1. 利用 Boolean() 函式轉型。
  2. 利用 !! 轉型,原理是利用!運算子自動轉型為相反的布林值後,在反轉回來。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
var flag = document.documentElement;    // 確認是否有此成員
console.log(Boolean(flag)); // true
console.log(!!flag); // true

console.log(!!0); // false
console.log(!!-1); // true
console.log(!!NaN); // false
console.log(!!Infinity); // true
console.log(!!-Infinity); // true
console.log(!!""); // false
console.log(!!"0"); // true,只有空字串是 false
console.log(!!"false"); // true,同上
console.log(!![]); // true
console.log(!!{}); // true
console.log(!!undefined); // false
console.log(!!null); // false
console.log(!!function(){}); // true
console.log(!!new Boolean(false)); // true,特別注意 object -> false -> true
console.log(!!new Number(0)); // true,同上
console.log(!!new String('')); // true,同上

總結來說,以下情況轉為布林時,結果會是 false

  1. Boolean 型別值為 FALSE 之變數。
  2. Number 型別值為 0 之變數。
  3. Number 型別值為 NaN 之變數。
  4. String 為空字串之變數。
  5. undefined
  6. null

數值 (Number)

語法

在 JavaScript 中的數字型別只有一種,所以可以把它想成自動判斷整數或浮點數,從整數的角度來看他的話可以有以下三種寫法:

  1. 十進位制。
  2. 十六進位制,以 0x 開頭。
  3. 八進位制,以 0 開頭。(八進位制並未定義在標準之中,僅在附錄的相容性章節。)

從浮點數來看的話,可以寫成科學記號的表示方式。

1
2
3
4
5
6
7
console.log(123);       // 123
console.log(0x123); // 291
console.log(0123); // 83
console.log(-1.23); // -1.23
console.log(.123); // 0.123
console.log(12e3); // 12000
console.log(12E-3); // 0.012

所以總結正規表示法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
integer     : [1-9][0-9]*
| 0

exponent : [eE][\+\-]?[0-9]+

decimal : integer(exponent)?
| integer\.[0-9]*exponent?
| \.[0-9]+exponent?

hexadecimal : 0[xX][0-9a-fA-F]+

octal : 0[0-7]+

number : decimal
| hexadecimal
| octal

正負號並不屬於實字的語法中,而是運算子的一部份。

數值的範圍

JavaScript 使用 64 位元浮點數來表示數字,所以整數部分介於 -9007199254740992(-253) 到 9007199254740992(253) 可以精確表示出來,浮點數格式則是最大 ±1.7976931348623157 x 10308 最小 ±5 x 10-324

可使用 JavaScript 的常數 Number.MAX_VALUE 取得可表示的最大數字部分 (次方數最大) 和 Number.MIN_VALUE 取得可表示的最小數字部分 (次方數最小,趨近零)。

1
2
console.log(Number.MAX_VALUE);      // 1.7976931348623157e+308
console.log(Number.MIN_VALUE); // 5e-324

特殊數值

NaN

NaN 表示 Not a number,當運算錯誤時就會得到這個結果,例如無法轉成數值的運算或除以0等情況。必須注意的一點是,NaN 只能使用 isNaN() 的函式來判斷是否為 NaN 的數值:

1
2
3
4
5
6
7
// NaN
console.log('b' - 1);
console.log(0 / 0);
console.log(parseFloat(undefined));

console.log(NaN == NaN); // false,即使是自己也不相等
console.log(isNaN(NaN)); // true

正無窮大

當一個數值大於可表示的最大值時,JavaScript 會使用 Infinity 的特殊數值來表示正無窮大。

1
2
console.log(Number.MAX_VALUE + 1e+291);     // 1.7976931348623157e+308,表示位數數值沒有增加,所以沒有變化
console.log(Number.MAX_VALUE + 1e+292); // Infinity,無法表示 1.7976931348623158e+308

負無窮大

相反的,當一個數值小於可表示的最小值時,JavaScript 會使用 -Infinity 的特殊數值來表示負無窮大。

1
2
console.log(-Number.MAX_VALUE - 1e+291);    // -1.7976931348623157e+308,表示位數數值沒有增加,所以沒有變化
console.log(-Number.MAX_VALUE - 1e+292); // -Infinity,無法表示 -1.7976931348623158e+308

轉型

數值可以用以下方式轉型:

  1. 利用 Number() 函式轉型。
  2. 利用 value - 0 轉型。原理是利用-運算子自動轉型,再減去一個不影響結果的數值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
var num = Number('123');
console.log(num); // 123
console.log(typeof(num)); // number

num = '123' - 0;
console.log(num); // 123
console.log(typeof(num)); // number

console.log(Number(false)); // 0
console.log(Number(true)); // 1
console.log(Number('')); // 0
console.log(Number('30')); // 30
console.log(Number('30cm')); // NaN
console.log(Number([])); // 0, 空陣列為0
console.log(Number([55, 66])); // NaN, 非空陣列為NaN
console.log(Number({})); // NaN
console.log(Number(function(){})); // NaN
console.log(Number(null)); // 0
console.log(Number(undefined)); // NaN
console.log(Number(new Boolean(false))); // 0
console.log(Number(new Number(0))); // 0
console.log(Number(new String(''))); // 0

除此之外,另外還有 parseInt()parseFloat() 兩種函式可以將字串解析成數字,這兩個函式會由左至右解析數字的部分,直到遇到非數字的部分;而 parseInt() 只處理整數部分,另外 parseInt() 和上面轉型的方式也可以解析十六進位的字串。包含上述的轉型都允許開頭或結尾有空白。

1
2
3
4
5
6
7
8
9
10
11
console.log(parseInt('169.99cm'));      // 169
console.log(parseFloat('169.99cm')); // 169.99
console.log(Number('169.99cm')); // NaN

console.log(parseFloat(' 2012 ')); // 2012
console.log(Number(' 2012 ')); // 2012

console.log(parseInt('0xFF')); // 255
console.log(parseFloat('0xFF')); // 0
console.log(Number('0xFF')); // 255
console.log('0xFF' - 0); // NaN

如果字串確定是數字形式的時候,parseInt()parseFloat() 也可以視為額外的轉型方法。

近似值

在電腦世界中的浮點數其實只是近似值,浮點數中的整數可能只是精確度到達一定程度而已,例如下面的例子:

1
2
3
console.log(Number.MIN_VALUE / 10); // 0
console.log(9007199254740992); // 9007199254740992
console.log(9007199254740993); // 9007199254740992,無法精確表示超過這個數值的整數

另外有些情況雖然看起來很正常,但仍然會得到錯誤的結果,如下面的些例子與一個變通的方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
var num = 8;
var num2 = (0.1 + 0.7) * 10;
console.log(num2); // 7.999999999999999
console.log(num == num2); // falsse
console.log(floatEqual(num, num2)); // true

// 誤差值小於 $precision 視為相等
function floatEqual(num, num2, precision) {
if (precision == undefined) {
precision = 0.0001;
}
return (Math.abs(num - num2) < precision);
}

字串 (String)

語法

字串有以下兩種使用方式:

  1. 單引號。
  2. 雙引號。

單引號字串中可以直接使用雙引號;反之亦然。字串實字不能直接斷行寫成多行,必須用運算子連接。一些範例如下:

1
2
3
4
5
6
console.log("I'm fine.");           // I'm fine.
console.log('He said, "Me, too."'); // He said, "Me, too."
console.log("my face"
+ "book is funny"); // my facebook is funny
console.log("非標準 \
斷行"); // 非標準 斷行

最後一個範例是一種非標準的寫法,請避免使用。

逸出字元

所謂逸出字元是為了某些特別的用途或能以此輸入打不出來的字,而定義的一種使用方式,在此的逸出字元以反斜線 (backslash) 開頭。例如,我們使用單引號做包夾,但字串中如果出現單引號,將會誤判為字串結束單引號,所以使用 \' 來表示字串中的單引號。使用字串可用的逸出字元如下:

符號說明
\b倒退鍵 (0x08)。
\t水平定位字元 (0x09)。
\n換行字元 (0x0A)。
\v垂直定位字元 (0x0B)。
\f跳頁字元 (0x0C)。
\r歸位字元 (0x0D)。
"雙引號字元 (0x22)。
'單引號字元 (0x27)。
\反斜線字元 (0x5C)。
\xXX or \x[0-9A-Fa-f]{2}以兩位數十六進位數字表示 Latin-1 字元。
\uXXXX or \u[0-9A-Fa-f]{4}以四位數十六進位數字表示 Unicode 字元。
\XXX or [0-7]{1,3}以一到三位八進位數字表示 Latin-1 字元。(八進位制並未定義在標準之中。)

範例如下:

1
console.log('I can\'t type \u5566');    // I can't type 啦

字串的操作

字串的連接

JavaScript中,字串使用加號 (+) 來作為連接運算子。

1
console.log('abc' + 'def'); // abcdef

字串的長度

可以使用 length 屬性取得字串的長度。

1
console.log('abcdef'.length);   // 6

字元的存取

JavaScript 中字串的字元是唯讀的,不能直接修改,但我們可以用以下方式讀取字串中的字元:

  1. 使用 charAt() 函式。
  2. 使用 [] 陣列索引方式。(在 ECMAScript v5 才有,較舊的瀏覽器如 IE7 並不支援。)

一些範例如下:

1
2
3
4
5
var s = 'Loser';
console.log(s.charAt(0)); // L
console.log(s[1]); // o
s[2] = 'v';
console.log(s); // Loser, you can't change

轉型

字串可以用以下方式轉型:

  1. 利用 String() 函式轉型。
  2. 利用 toString()函式轉型。
  3. 利用 value + '' 轉型。原理是利用 + 運算子自動轉型,再加上空字串。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var str = String(true);
console.log(str); // true
console.log(typeof(str)); // string

var str = true.toString()
console.log(str); // true
console.log(typeof(str)); // string

var str = true + '';
console.log(str); // true
console.log(typeof(str)); // string

console.log(String(false)); // false
console.log(String(true)); // true
console.log(String(178)); // 178
console.log(String(NaN)); // NaN
console.log(String(Infinity)); // Infinity
console.log(String(-Infinity)); // -Infinity
console.log(String([])); // 空字串
console.log(String([55, 66])); // 55,66
console.log(String({})); // [object Object]
console.log(String(function(){})); // function (){}
console.log(String(null)); // null
console.log(String(undefined)); // undefined
console.log(String(new Boolean(false))); // false
console.log(String(new Number(0))); // 0
console.log(String(new String(''))); // 空字串

nullundefined 的時候無法使用 toString()

延伸閱讀

上一篇 JavaScript 教學 - 基本語法 (Syntax)
下一篇 JavaScript 教學 - 資料型態 (Data Type) - 下