美思 現代 [JavaScript] 程式設計教學:資料型態 (Data Types)

Facebook Twitter LinkedIn LINE Skype EverNote GMail Yahoo Email

JavaScript 是動態型別的 (Dynamically-typed) 語言

在 JavaScript 中,變數沒有綁定特定的型別,而是由資料本身來決定變數的型別。以下程式碼是合法的 JavaScript 程式:

// x is a boolean.
let x = true;
assert(typeof x === "boolean", "x should be a boolean");

// x becomes a string.
x = "hello";
assert(typeof x === "string", "x should be a string");

// x becomes a number.
x = 123;
assert(typeof x === "number", "x should be a number");

// x becomes an object literal.
x = {};
assert(typeof x === "object", "x should be a object");

// x becomes a function object.
x = (a, b) => a + b;
assert(typeof x === "function", "x should be a function object");

// Home-made `assert`
function assert(cond, msg) {
    if (!(cond)) {
        throw msg;
    }
}

在此例中,變數 x 的型別改變數次,但程式仍可正常運作。當然,在實務上,我們不會一直改變變數的資料型別。

JavaScript 的基礎型別 (Primitive Type)

基礎型別就是程式中基本的資料型態,非物件的型別,包括以下數種:

  • 空值 (null)
  • 未定義 (undefined)
  • 布林 (boolean)
  • 數字 (number)
  • 字串 (string)
  • (新) 符號 (symbol)

空值

ECMAScript 有兩種空值,分別為 nullundefined,兩者的意義略為不同,null 代表有值,而該值為空,而 undefined 表示值尚未定義。一般來說,明確使用 null 表示空值比較好,因為使用 undefined 會誤以為是忘了定義值。

布林 (Boolean)

布林只有兩個值,包括 truefalse,表示邏輯上的真和假。我們較少直接寫出 truefalse,而會撰寫條件式來改變程式執行流程。除了 truefalse 外,程式設計者也要知道何謂 truthy 和 falsy 值,簡單地說,就是會判定為真或假的值,以下為 falsy 值:

  • undefined
  • null
  • false
  • 0
  • NaN
  • '' (空字串)

除了少數 falsy 值外,其他都是 truthy 值。要注意的是,以下是 truthy 值:

  • {} (空物件)
  • [] (空陣列)
  • " " (含空格的字串)

數字 (Number)

ECMAScript 只有一種數字型態,就是倍精度浮點數 (double-precision floating-point number)。如果只進行整數部分的運算,不會有什麼問題,但在進行浮點數運算時,就要注意微小的誤差所帶來的錯誤:

assert(0.1 + 0.2 - 0.3 === 0.0, "It should be equal");  // Failed!

// Home-made `assert`
function assert(cond, msg) {
    if (!(cond)) {
        throw msg;
    }
}

這些誤差來自於電腦內部儲存浮點數的方式,在電腦內部,浮點數是以其近似值的方式來儲存,每次運算都會帶來一些微小的誤差,對此議題有興趣的讀者可以參考一些計算機概論相關的書籍。

字串 (String)

ECMAScript 的字串有三種:

  • 單引號字串
  • 雙引號字串
  • (新) 字串樣板

在字串中,跳脫字元 (escaped character) 指的是無法用鍵盤直接輸入的特殊符號,像是換行 "\n"、TAB 符號 "\t" 等。ECMAScript 中,不論是單引號字串或是雙引號字串皆能處理跳脫字元,這和其他語言略有不同,如下例:

console.log('123\t456');
console.log("123\t456");

那麼,為什麼要區分兩種字串呢?主要是為了跳脫單引號或雙引號本身,如下例:

console.log('Don\'t talk with me.');
console.log("Don't talk with me.");

在上例中,為了要在單引號字串中使用單引號,必需要額外地使用跳脫字元,但在雙引號字串中則不需要。大部分情形下,使用雙引號字串較佳,因為一般文字中使用雙引號的機會較少,如果字串中可能會用到雙引號,則改用單引號字串。

附帶一提,如果要跳脫跳脫字元本身,就使用兩個跳脫字元 "\\",如下例:

console.log('C:\\User\\Michelle>');

字串樣板是為了簡化字串安插所加入的新語法。在加入這個語法前,若要在字串中安插動態資料,得用一堆加號進行字串相接,不但難寫而且難看,這個語法大大簡化字串安插的程式碼。如下例:

// String concatenation (old school).
let t1 = "2 + 3 = " + (2 + 3) + "\n"
  + "2 * 3 = " + (2 * 3);

// String template.
let t2 = `2 + 3 = ${2 + 3}
2 * 3 = ${2 * 3}`;

// Check whether two strings are equal.
if (t1 !== t2 ) {
    throw "It should be equal";
}

(新) Symbol (符號)

符號是 ECMAScript 6 新的語法,主要是用來建立獨一無二的值,如下例:

const RED = Symbol();
const BLUE = Symbol();

if (RED == BLUE) {
    throw "It should not be equal";
}

由於 ECMAScript 沒有內建的列舉 (enum) 型別,符號也可用來替代列舉。

物件型別 (Object Type)

ECMAScript (JavaScript) 建立物件 (object) 的方法有三種:

  • {} (物件實字)
  • 函式物件
  • (新) class 保留字

前兩種是原本的 JavaScript 語法,而 class 算是一種語法糖。我們會在後文中說明建立物件的方法。

JavaScript 沒有類別 (class) 的概念,因為 JavaScript 的物件系統是以原型 (prototype) 為基礎。

JavaScript 的內建物件

JavaScript 內建以下物件:

  • Number (數字)
  • String (字串)
  • Boolean (布林)
  • Array (陣列)
  • Date (日期)
  • RegExp (常規表示式)
  • (新) Map 和 WeakMap
  • (新) Set 和 WeakSet

從內建物件的名稱,就可以猜出來該物件的功能。我們將於後文中說明。

關於作者

身為資訊領域碩士,美思認為開發應用程式的目的是為社會帶來價值。如果在這個過程中該軟體能成為永續經營的項目,那就是開發者和使用者雙贏的局面。

美思喜歡用開源技術來解決各式各樣的問題,但必要時對專有技術也不排斥。閒暇之餘,美思將所學寫成文章,放在這個網站上和大家分享。