一、有哪些資料型別?
JavaScript
的資料型別分為兩大類,分別為基本資料型別和引用資料型別。
基本型別又叫值型別或者簡單型別,包括null
,undefined
,boolean
,string
,number
,symbol
。
引用型別又叫複雜型別或者物件型別,包括Object
,Array
,Date
,Function
,Map
,Set
等。
不同的是基本型別的值儲存在棧記憶體中,按值訪問。引用型別儲存在堆記憶體中,按引用(地址、指標)訪問。
舉個例子:
// 基本型別
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種結果:number
、string
、boolean
、undefined
、symbol
、object
、function
。
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
可以用來檢測基本型別,但是檢測引用型別時並不能返回具體的資料型別,這個時候可以用instanceof
。instanceof
是通過原型鏈去判斷的,通過測試左邊物件的原型鏈上是否有右邊這個物件建構函式的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
非常相似。它的作用是,可以檢測例項物件是由哪一個建構函式產生的。它也可以檢測基本資料型別。但是如果重寫prototype
,constructor
可以會被改變。
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()
這個是檢測資料型別最推薦最常用的方法,可以更加準確地判斷任何資料型別。toString
是Object
原型物件上的一個方法,這個方法預設返回其呼叫者的具體型別,用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被指定為整形,那麼它就不能作為字串來使用。如Java
、Python
就是強型別定義語言。
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、轉換為布林值
布林表示一種邏輯實體,可以有兩個值:true
和false
。在條件判斷時,false
、''
、null
、undefined
、NaN
、0
、-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、判斷資料型別的四種方法:typeof
、instanceof
、constructor
、Object.prototype.toSting.call()
。
3JavaScript
資料轉換的三種情況:轉換為布林值、字串或者數字。