JavaScript—八種數據類型最全總結(檢測與轉換)

數據類型

數據類型檢測

typeof

可檢測基本數據類型和function,沒法檢測引用數據類型面試

var arr = [
    null,      // object
    undefined, // undefined
    true,      // boolean
    12,        // number
    'haha',    // string
    Symbol(),  // symbol
    20n,       // bigint
    function(){}, // function
    {},        // object
    [],        // object
]
for (let i = 0; i < arr.length; i++) {
    console.log(typeof arr[i])
}

instanceof

沒法檢測基本數據類型,可檢測function 、引用類型和繼承關係數組

var arr = [
    // { 'value': null, 'type': null}, ----> error
    // { 'value': undefined, 'type': undefined},   ----> error
    { 'value': true, 'type': Boolean},      // false
    { 'value': 12, 'type': Number},         // false
    { 'value': 'haha', 'type': String},     // false
    { 'value': Symbol(), 'type': Symbol},   // false
    { 'value': 20n, 'type': BigInt},        // false
    { 'value': function(){}, 'type': Function}, // true
    { 'value': {}, 'type': Object},         // true
    { 'value': [], 'type': Array},          // true
]
for (let i = 0; i < arr.length; i++) {
    console.log(arr[i].value instanceof arr[i].type)
}

instanceof 除了能夠檢測類型外,還能夠在繼承關係的檢測中使用瀏覽器

function Aoo(){} 
function Foo(){} 
Foo.prototype = new Aoo(); // JavaScript 原型繼承
 
var foo = new Foo(); 
console.log(foo instanceof Foo) // true 
console.log(foo instanceof Aoo) // true

constructor

提示:雖可檢測,但 prototype 可被改寫,constructor 會改變,不建議使用該方法判斷。安全

var arr = [
    // { 'value': null, 'type': Null}, ----> error
    // { 'value': undefined, 'type': Undefined},   ----> error
    { 'value': true, 'type': Boolean},     // true
    { 'value': 12, 'type': Number},        // true
    { 'value': 'haha', 'type': String},    // true
    { 'value': Symbol(), 'type': Symbol},  // true
    { 'value': 20n, 'type': BigInt},       // true
    { 'value': function(){}, 'type': Function}, // true
    { 'value': {}, 'type': Object},       // true
    { 'value': [], 'type': Array},        // true
]
for (let i = 0; i < arr.length; i++) {
    console.log(arr[i].value.constructor == arr[i].type)
}

Object.prototype.toString.call()

通常類型都能檢測,建議使用。函數

var arr = [
    null,        // [object Null]
    undefined,   // [object Undefined]
    true,        // [object Boolean]
    12,          // [object Number]
    'haha',      // [object String]
    Symbol(),    // [object Symbol]
    20n,         // [object BigInt]
    function(){},// [object Function]
    {},          // [object Object]
    [],          // [object Array]
    new Date(),  // [object Date]
    new RegExp(),// [object RegExp]
    new Error(), // [object Error]
]
for (let i = 0; i < arr.length; i++) {
    console.log(Object.prototype.toString.call(arr[i]))
}

數據類型轉換

將值從一種類型轉換爲另外一種類型一般稱爲類型轉換(type casting),這是顯式的狀況;隱式的狀況稱爲強制類型轉換(coercion)。this

類型轉換髮生在靜態類型語言的編譯階段,而強制類型轉換則發生在動態類型語言的運行時(runtime)。spa

強制類型轉換又分如下兩種:prototype

  • 顯式強制類型轉換(explicit coercion)
  • 隱式強制類型轉換(implicit coercion)

抽象操做

「抽象操做」(即「僅供內部使用的操做」),是js的內置函數。code

String()

處理非字符串到字符串的強制類型轉換。對基本類型有效,對引用類型(object)無效。對象

String(12);           // "12"
String("haha");       // "haha"
String(null);         // "null"
String(undefined);    // "undefined"
String(true);         // "true"
String({a: '12'});    // [object Object]
value值 原始類型 轉換後
12 number "12"
haha string "haha"
null null "null"
undefined undefined "undefined"
true boolean "true"
{a: '12'} object [object Object]

JSON.stringify(..)

JSON 字符串化和 toString() 的效果基本相同,只不過序列化的結果老是字符串。

1. 安全的 JSON 值轉換

JSON.stringify(12);           // "12"
JSON.stringify("str");        // ""str""
JSON.stringify(null);         // "null"
JSON.stringify(true);         // "true"
JSON.stringify({a: '12'});    // "{"a":"12"}"
value值 原始類型 轉換後
12 number "number"
haha string ""haha"" (含有雙引號的字符串)
null null "null"
true boolean "true"
{a: '12'} object "{"a":"12"}"

2. 不安全的 JSON 值轉換

JSON.stringify(..) 在對象中遇到 undefinedfunctionsymbol會自動將其忽略,在
數組中則會返回 null(以保證單元位置不變)。

JSON.stringify( undefined );    // undefined
JSON.stringify( function(){} ); // undefined
JSON.stringify(
 [ 1, undefined, function(){}, 4]
); // "[1, null, null, 4]"
JSON.stringify(
 { a:2, b:function(){} }
); // "{"a":2}

對包含循環引用的對象執行 JSON.stringify(..) 會出錯

var o = { };
var a = { 
    b: 42,
    c: o, // 循環引用
    d: function(){}
};
// 在a中建立一個循環引用
o.e = a;
// 循環引用在這裏會產生錯誤
// JSON.stringify( a );
// JSON.stringify( o );

3. 自定義 JSON 序列化

var a = { 
    b: 42,
    c: 'haha',
    d: function(){}
};
// 自定義的JSON序列化
a.toJSON = function() {
    // 序列化僅包含b
    return { b: this.b };
};

JSON.stringify( a ); // "{"b":42}"

Number()

處理非數字值到數字的強制類型轉換, 處理失敗時返回NaN。

Number("33");            // 33
Number(null);            // 0
Number(undefined);       // NaN
Number(true);            // 1
Number(false);           // 0
Number({a: '12'});       // NaN
Number(function(){});    // NaN
value值 原始類型 轉換後value值
"33" string 33
<span class="red">null</span> null <span class="red">0</span>
undefined undefined NaN
true boolean 1
false boolean 0
{a: '12'} object NaN

八進制和十六進制

  • 若是前綴爲 0,則 JavaScript 會把數值常量解釋爲八進制數
  • 若是前綴爲 0 和 "x",則解釋爲十六進制數
// 八進制的377 ->  十進制255
Number(0377); // 255
// 十六進制 -> 十進制的255
Number(0xFF); // 255

對象和數組

對象(包括數組)會首先被轉換爲相應的基本類型值,若是返回的是非數字的基本類型值,則再遵循以上規則將其強制轉換爲數字。

爲了將值轉換爲相應的基本類型值,抽象操做會檢查該值是否有 valueOf() 方法。若是有而且返回基本類型值,就使用該值進行強制類型轉換。若是沒有就使用 toString()
的返回值(若是存在)來進行強制類型轉換。若是 valueOf() 和 toString() 均不返回基本類型值,會產生 TypeError 錯誤。

從 ES5 開始,使用 Object.create(null) 建立的對象 [[Prototype]] 屬性爲 null,而且沒有 valueOf() 和 toString() 方法,所以沒法進行強制類型轉換。
var a = {
    valueOf: function(){
        return "42";
    }
};
var b = {
    toString: function(){
        return "42";
    }
};

var c = [4,2];
c.toString = function(){
    return this.join( "" ); // "42"
};
Number( a ); // 42
Number( b ); // 42
Number( c ); // 42
Number( "" ); // 0
Number( [] ); // 0
Number( [ "abc" ] ); // NaN
Number(['1']);         // 1
Number(['1', '2']);    // NaN

Boolean()

除了假值和假值對象,其餘的均可以看作是真值。

// 假值
Boolean("");         // false 
Boolean(undefined);  // false 
Boolean(null);       // false 
Boolean(false);      // false 
Boolean(+0);         // false 
Boolean(-0);         // false 
Boolean(0);          // false 
Boolean(NaN);        // false 

// 假值對象(瀏覽器本身建立的對象)
Boolean(document.all) // false
...

// 真值
Boolean([]);             // true
Boolean({});             // true
Boolean(function(){});   // true
Boolean(1)               // true
...

顯式強制類型轉換

字符串與數字

1. String() 和 Number()
2. toString()

toString() 是顯式的,不過其中涉及隱式轉換。由於toString() 對 number 這樣的基本類型值不適用,因此 JavaScript 引擎會自動爲 number 類型建立一個封裝對象,而後對該對象調用 toString()。這裏顯式轉換中含有隱式轉換。

var a = 42;
a.toString(); // "42"
3. 一元運算 +-

一元運算 + 被廣泛認爲是顯式強制類型轉換

var c = "3.14";
var d = +c;
var e = -c; // 會反轉符號位
var f = - -c; // 中間要有空格

d; // 3.14
e; // -3.14
f; // 3.14

// 日期顯式轉換爲數字
var d = new Date;
+d; // 時間戳 1595836134918

// 更好的辦法(建議使用)
var timestamp = Date.now()
4. ~ 運算符(非)

~ 運算符(位非)用於對一個二進制操做數逐位進行取反操做。

  • 第 1 步:把運算數轉換爲 32 位的二進制整數。
  • 第 2 步:逐位進行取反操做。
  • 第 3 步:把二進制反碼轉換爲十進制浮點數。
~12; // -13

~ 和 indexOf() 結合使用

var a = "Hello World";

if (~a.indexOf( "lo" )) { // -4 -> 真值 -> true
 // 找到匹配!
}

if (!~a.indexOf( "ol" )) { // -4 -> 真值 -> true
 // 沒有找到匹配!
}

顯式解析數字字符串

  • Number():將非數字值轉換爲數字,處理失敗時返回NaN
  • parseInt(): 僅針對字符串值,其餘類型無效,返回一個整數
  • parseFloat():做用和parseInt() 一致,但可返回浮點數
var a = "42";
var b = "42px";

Number( a ); // 42
parseInt( a ); // 42

Number( b ); // NaN
parseInt( b ); // 42

var c = '12.3333'
parseInt( c ); // 12
parseFloat( c ); // 12.3333

顯式轉換爲布爾值

1. Boolean()
2. !!

一元運算符 ! 顯式地將值強制類型轉換爲布爾值,它同時還將真值反轉爲假值(或假值反轉爲真值)。

顯式強制類型轉換爲布爾值最經常使用的方強制類型轉換方法是 !!,由於第二個 ! 會將結果反轉回原值。

var a = "0";
var b = [];
var c = {};
var d = "";
var e = 0;
var f = null;
var g; // undefined

!!a; // true
!!b; // true
!!c; // true
!!d; // false
!!e; // false
!!f; // false
!!g; // false
value值 Boolean()轉換 !!轉換
"" false false
0 false false
null false false
undefined false false
<span class="red">"0"</span> <span class="red">true</span> <span class="red">true</span>
[] true true
{} true true
在 if(..).. 這樣的布爾值上下文中,若是沒有使用 Boolean(..) 和 !!,就會自動隱式地進行 ToBoolean 轉換。

隱式強制類型轉換

自動轉換類型

當 JavaScript 嘗試操做一個 "錯誤" 的數據類型時,會自動轉換爲 "正確" 的數據類型。

5 + null    // 返回 5         null 轉換爲 0
"5" + null  // 返回"5null"   null 轉換爲 "null"
"5" + 1     // 返回 "51"      1 轉換爲 "1" 
"5" - 1     // 返回 4         "5" 轉換爲 5
"5" * true  // 返回 5         "true" 轉換爲 1

自動轉換爲字符串

當你嘗試輸出一個對象或一個變量時 JavaScript 會自動調用變量的 toString() 方法:

document.getElementById("demo").innerHTML = myVar;

myVar = {name:"Fjohn"}  // toString 轉換爲 "[object Object]"
myVar = [1,2,3,4]       // toString 轉換爲 "1,2,3,4"
myVar = new Date()      // toString 轉換爲 "Fri Jul 18 2014 09:08:55 GMT+0200"

數字和布爾值也常常相互轉換:

myVar = 123             // toString 轉換爲 "123"
myVar = true            // toString 轉換爲 "true"
myVar = false           // toString 轉換爲 "false"

類型轉換小結

下表展現了使用不一樣的數值轉換爲數字(Number), 字符串(String), 布爾值(Boolean):

原始值 轉換爲數字 轉換爲字符串 轉換爲布爾值
false 0 ""false"" false
true 1 "true" true
0 0 "0" false
1 1 "1" true
"0" 0 "0" true
"000" 0 "000" true
"1" 1 "1" true
NaN NaN "NaN" false
"" 0 "" false
[ ] 0 "" true
function(){} NaN "function(){}" true
{ } NaN "[object Object]" true
null 0 "null" false
undefined NaN "undefined" false
Infinity Infinity "Infinity" true
-Infinity -Infinity "-Infinity" true

經典面試題

1 + '1' 
true + 0
{}+[]
4 + {} 
4 + [1] 
'a' + + 'b'
console.log ( [] == 0 )
console.log ( ! [] == 0 )
console.log ( [] == ! [] )
console.log ( [] == [] )
console.log({} == !{})
相關文章
相關標籤/搜索