JS的資料型別

百聞一見發表於2019-10-20

一、有哪些資料型別?

JavaScript的資料型別分為兩大類,分別為基本資料型別和引用資料型別。

基本型別又叫值型別或者簡單型別,包括nullundefinedbooleanstringnumbersymbol。 引用型別又叫複雜型別或者物件型別,包括ObjectArrayDateFunctionMapSet等。

不同的是基本型別的值儲存在棧記憶體中,按值訪問。引用型別儲存在堆記憶體中,按引用(地址、指標)訪問。

舉個例子:

// 基本型別
var a = 5;
var b = a;
b = 8;
console.log(a,b); // 5 8
// 引用型別
var c = { text: 'Hello World!' };
var d = c;
d.text = 'Hi!';
console.log(c.text, d.text); // Hi! Hi!
複製程式碼

二、如何判斷資料型別?

1、typeof

typeof可以用來檢測給定變數的資料型別,它會返回一個表示資料型別的字串,可能返回7種結果:numberstringbooleanundefinedsymbolobjectfunction

typeof 123; // number
typeof '123'; // string
typeof true; // boolean
typeof undefined; // undefined
typeof Symbol(); // symbol
typeof null; // object
typeof {}; // object
typeof function () {} // function
複製程式碼

typeof對於基本型別來說,除了null都可以顯示正確的型別。對於引用型別來說,除了函式都會顯示object。所以說可以用typeof來判斷基本資料型別,但是要注意null的情況。

null返回object是原因是這樣的:JavaScript中不同的值在底層都表示為二進位制,object在二進位制中前三位對應的值是000。而null在二進位制中32位都是0,自然前三位也是0。所以typeof null會返回object

2、instanceof

typeof可以用來檢測基本型別,但是檢測引用型別時並不能返回具體的資料型別,這個時候可以用instanceofinstanceof是通過原型鏈去判斷的,通過測試左邊物件的原型鏈上是否有右邊這個物件建構函式的prototype屬性來判斷的。表示式為:A instanceof B,即判斷A是否為B的例項,是則返回true,否則返回false

[] instanceof Array; // true
{} instanceof Object; // true
new Function() instanceof Function; // true
new Date() instanceof Date; // true
new Map() instanceof Map; // true
new Set() instanceof Set; // true
// 陣列還可以用ES6新增的Array.isArray()來判斷
Array.isArray([]); // true
// instanceof 還可以測試自定義型別
function Person(){};
new Person() instanceof Person; // true
new Person() instanceof Object; // true
複製程式碼

值得注意的是所有引用型別用instanceof檢測Object都會返回true,這是因為引用資料型別的原型鏈上都存在有Object屬性。即所有引用型別的資料都是Object的例項。

另外,基本資料型別不能通過instanceof來判斷。

下面來簡單實現一下instanceof

function myInstanceof(A, B) {
    var A = A.__proto__;
    var B = B.prototype;
    while (1) {
        if (A === null) return false;
        else if (A === B) return true;
        A = A.__proto__;
    }
}
複製程式碼

3、constructor

constructor即建構函式,作用和instanceof非常相似。它的作用是,可以檢測例項物件是由哪一個建構函式產生的。它也可以檢測基本資料型別。但是如果重寫prototypeconstructor可以會被改變。

function F(){};
var f = new F();
f.constructor === F; // true
// 重寫prototype
F.prototype = { a: '' };
var f1 = new F();
f1.constructor === F; // false
// 重寫原型時可以給constructor賦值,這樣就不會被改變
F.prototype = {
    constructor: F, 
   a: '',
};
var f2 = new F();
f2.constructor === F; // true 
// 基本型別
var num = 1;
num.constructor === Number; // true
'1'.constructor === String; // true
true.constructor === Boolean; // true
Symbol().constructor === Symbol; // true
// 對於特殊的null和undefined,瀏覽器並不允許在外面訪問使用,所以不能用constructor來判斷
複製程式碼

4、Object.prototype.toString.call()

這個是檢測資料型別最推薦最常用的方法,可以更加準確地判斷任何資料型別。toStringObject原型物件上的一個方法,這個方法預設返回其呼叫者的具體型別,用call改變方法中的this關鍵字的指向,然後返回當前方法的執行主體(方法中this)所屬類的詳細資訊,返回格式為[object String]

toString.call(''); // [object String]
toString.call(1); // [object Number]
toString.call(null); // [object Null]
toString.call(undefined); // [object Undefined]
toString.call(true); // [object Boolean]
toString.call(Symbol()); // [object Symbol]
toString.call({}); // [object Object]
toString.call([]); // [object Array]
toString.call(new Function()); // [object Function]
toString.call(new Date()); // [object Date]
toString.call(new Map()); // [object Map]
toString.call(new Set()); // [object Set]
toString.call(new Error()); // [object Error]
複製程式碼

三、資料型別的轉換

JavaScript是一種弱型別的語言,也可以說是動態型別的語言。動態型別,就是一個變數可以被賦予不同的資料型別,可以根據使用場景來變化,在計算時可以隱式轉換它的型別。

與之不同的是強型別語言(強制資料型別定義的語言),也就是說,如果一個變數被指定了某一個資料型別,那它就一直是這個資料型別。舉個例子:如果變數a被指定為整形,那麼它就不能作為字串來使用。如JavaPython就是強型別定義語言。

var num = 1;
console.log(typeof num); // number
num = '1';
console.log(typeof num); // string
num = true;
console.log(typeof num); // boolean
num = new Date();
console.log(typeof num); // object
console.log(1 + '1'); // 11
console.log(1 + true); // 2
複製程式碼

資料轉換的三種情況

1、轉換為布林值

布林表示一種邏輯實體,可以有兩個值:truefalse。在條件判斷時,false''nullundefinedNaN0-0這些值為false,其他都為true

2、轉換為字串 X.toString()、String()、+''

// (1)數字
(11).toString(10); // '11' // 對應的字串
(12).toString(2); // '1100' // 可以轉換為不同的進位制
// (2)陣列
[1, 2].toString(); // '1,2'
// (3)物件
({}).toString(); // [object Object] // 都會轉換為[object Object] 
// (4)其他
true.toString(); // 'true' // 對應的字串
複製程式碼

3、轉換為數字 Number()、parseInt()、parseFloat()

// (1)字串
Number('1'); // 1
Number('a'); // NaN
// (2)boolean
Number(true); // 1 // true轉1,false轉0
// (3)null
Number(null); // 0
// (4)undefined
Number(undefined); // NaN
// (5)symbol
Number(Symbol()) // 報錯
// (6)陣列
Number([]); // 0 // 空陣列轉為0
Number([1]); // 1 // 存在一個元素則將這個元素轉為數字
Number([1, 2]); // NaN //存在多個元素則轉換為NaN
// (7)除了陣列的引用型別
Number({}); // NaN 
複製程式碼

小結

1、JavaScript的資料型別分為兩大類:基本型別和引用型別。

2、判斷資料型別的四種方法:typeofinstanceofconstructorObject.prototype.toSting.call()

3JavaScript資料轉換的三種情況:轉換為布林值、字串或者數字。

相關文章