每一種編程語言都有數據結構,但他們各有不同之處。JavaScript 是一種動態語言,變數的類型不用提前聲明,你可以使用同一個變數來保存不同的數據類型。
每一種編程語言都有數據結構,但他們各有不同之處。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 %}
原始數據類型:
- Undefined
- Null
- Boolean
- Number
- String
- Symbol (ECMAScript 2015)
判斷方法
我們可以透過使用typeof
和Object.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 的:
- Let val be the result of evaluating UnaryExpression.
- If Type(val) is Reference, then a. If IsUnresolvableReference(val) is true, return “undefined”.
- Set val to ? GetValue(val).
- Return a String according to Table 35.
Table 35: typeof Operator Results
val 的類型 | 結果 |
---|---|
Item One | Item Two |
Type of val | Result |
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():
- If the
this
value isundefined
, return"[object Undefined]"
. - If the
this
value isnull
, return"[object Null]"
. - Let
O
be ! ToObject(this
value). - Let
isArray
be ? IsArray(O
). - If
isArray
istrue
, letbuiltinTag
be"Array"
. - Else if
O
is a String exotic object, letbuiltinTag
be"String"
. - Else if
O
has a [[ParameterMap]] internal slot, letbuiltinTag
be"Arguments"
. - Else if
O
has a [[Call]] internal method, letbuiltinTag
be"Function"
. - Else if
O
has an [[ErrorData]] internal slot, letbuiltinTag
be"Error"
. - Else if
O
has a [[BooleanData]] internal slot, letbuiltinTag
be"Boolean"
. - Else if
O
has a [[NumberData]] internal slot, letbuiltinTag
be"Number"
. - Else if
O
has a [[DateValue]] internal slot, letbuiltinTag
be"Date"
. - Else if
O
has a [[RegExpMatcher]] internal slot, letbuiltinTag
be"RegExp"
. - Else, let
builtinTag
be"Object"
. - Let
tag
be ? Get(O
, @@toStringTag). - If Type(
tag
) is not String, lettag
bebuiltinTag
. - Return the String that is the result of concatenating
"[object "
,tag
, and"]"
.