每一種編程語言都有數據結構,但他們各有不同之處。JavaScript 是一種動態語言,變數的類型不用提前聲明,你可以使用同一個變數來保存不同的數據類型。

var a = 'apple'; // String type
var a = 42; // Number type
var a = true; // Boolean type

這就和Python的寫法差不多:

a = 'apple' // String type
a = 42 // Number type
a = True // Boolean type

數據類型

ECMAScript 標準明確定義了7種數據類型:6種原始類型 (Primitive value) 和Object。

{% img /img/javascript-data-structures.svg 300 auto JavaScript Data Structure %}

原始數據類型:

  1. Undefined
  2. Null
  3. Boolean
  4. Number
  5. String
  6. Symbol (ECMAScript 2015)

判斷方法

我們可以透過使用typeofObject.prototype.toString()來判斷數據類型。

typeof

在 JavaScript 誕生之時,數值是由一個標籤以及實際數據值表示的。基本類型的標籤是 1,而對象類型的標籤是 0。

由於null代表的是空指針(全部都是 0),null的類型標籤會是0。如果你在 console 直接輸入typeof null的話,就會得到 "object" 的結果,雖然這不是我們想要的值。。。

typeof undefined; // "undefined"
typeof Boolean;   // "function"
typeof true;      // "boolean"
typeof 42;        // "number"
typeof "42";      // "string"
typeof Symbol();  // "symbol"

我們可以看一下ECMAScript是怎樣定義typeof的:

  1. Let val be the result of evaluating UnaryExpression.
  2. If Type(val) is Reference, then a. If IsUnresolvableReference(val) is true, return "undefined".
  3. Set val to ? GetValue(val).
  4. Return a String according to Table 35.

Table 35: typeof Operator Results

val 的類型結果
Item OneItem Two
Type of valResult
Undefined"undefined"
Null"object"
Boolean"boolean"
Number"number"
String"string"
Symbol"symbol"
Object (ordinary and does not implement [[Call]])"object"
Object (standard exotic and does not implement [[Call]])"object"
Object (implements [[Call]])"function"
Object (non-standard exotic and does not implement [[Call]])Implementation-defined. Must not be "undefined", "boolean", "function", "number", "symbol", or "string".

另外,如果直接用typeof來判斷 NaN 的話,它會返回"number",對於 NaN 我們可以用isNaN方法來判斷是否一個數字。

typeof NaN; // "number"
isNaN(NaN); // true

Object.prototype.toString()

我們可以利用Object.prototype.toString.call()或者Object.prototype.toString.apply()這兩個方法判斷 Object 的類型,以及 null:

Object.prototype.toString.call(undefined);   // "[object Undefined]"
Object.prototype.toString.call(new Date);    // "[object Date]"
Object.prototype.toString.call(new String);  // "[object String]"
Object.prototype.toString.call(Math);        // "[object Math]"
Object.prototype.toString.call(null);        // "[object Null]"

ECMAScript 19.1.3.6 明確定義 Object.prototype.toString():

  1. If the this value is undefined, return "[object Undefined]".
  2. If the this value is null, return "[object Null]".
  3. Let O be ! ToObject(this value).
  4. Let isArray be ? IsArray(O).
  5. If isArray is true, let builtinTag be "Array".
  6. Else if O is a String exotic object, let builtinTag be "String".
  7. Else if O has a [[ParameterMap]] internal slot, let builtinTag be "Arguments".
  8. Else if O has a [[Call]] internal method, let builtinTag be "Function".
  9. Else if O has an [[ErrorData]] internal slot, let builtinTag be "Error".
  10. Else if O has a [[BooleanData]] internal slot, let builtinTag be "Boolean".
  11. Else if O has a [[NumberData]] internal slot, let builtinTag be "Number".
  12. Else if O has a [[DateValue]] internal slot, let builtinTag be "Date".
  13. Else if O has a [[RegExpMatcher]] internal slot, let builtinTag be "RegExp".
  14. Else, let builtinTag be "Object".
  15. Let tag be ? Get(O, @@toStringTag).
  16. If Type(tag) is not String, let tag be builtinTag.
  17. Return the String that is the result of concatenating "[object ", tag, and "]".

參考資料

  1. ECMAScript® 2018 Language Specification
如果你覺得我的文章對你有幫助的話,希望可以推薦和交流一下。歡迎關注和 Star 本博客或者關注我的 Github