編程語(yǔ)言都具有內(nèi)建的數(shù)據(jù)結(jié)構(gòu),JavaScript 也不例外。JavaScript 是一種弱類(lèi)型或者說(shuō)動(dòng)態(tài)語(yǔ)言。它不用提前聲明變量的類(lèi)型,在程序運(yùn)行過(guò)程中,類(lèi)型會(huì)被自動(dòng)確定。這點(diǎn)事非常關(guān)鍵的,可以說(shuō)JS 靈活,沒(méi)有這么多限制,但是,這常常是BUG出現(xiàn)的原因所在。
因此,JS 變量的數(shù)據(jù)類(lèi)型檢測(cè)就是十分重要的。
在最新的 ECMAScript 標(biāo)準(zhǔn)中定義了 7 種數(shù)據(jù)類(lèi)型:
- 6 種基本數(shù)據(jù)類(lèi)型:Boolean、 Null、 Undefined、 Number、 String、 Symbol(ECMAScript 6 新定義)
- 1 種復(fù)雜數(shù)據(jù)類(lèi)型:Object
先來(lái)看 6 種基本數(shù)據(jù)類(lèi)型:
- Undefined
Undefined 類(lèi)型只有一個(gè)值,就是特殊的 Undefined。一個(gè)沒(méi)有被賦值的變量會(huì)有個(gè)默認(rèn)值 undefined。
var message;
typeof message; // "undefined"
- Null
Null 類(lèi)型是第一個(gè)只有只一個(gè)值得數(shù)據(jù)類(lèi)型,這是特殊值就是null。null值表示一個(gè)空對(duì)象指針。
var message = null;
typeof message; // "object"
- Boolean
Boolean 表示一個(gè)邏輯實(shí)體,可以有兩個(gè)值:true 和 false。
var found = true;
var lost = false;
typeof found; // "boolean"
typeof lost; // "boolean"
- Number
根據(jù) ECMAScript 標(biāo)準(zhǔn),JavaScript 中只有一種數(shù)字類(lèi)型:基于 IEEE 754 標(biāo)準(zhǔn)的雙精度 64 位二進(jìn)制格式的值(-(263 -1) 到 263 -1)。它并沒(méi)有為整數(shù)給出一種特定的類(lèi)型。除了能夠表示浮點(diǎn)數(shù)外,還有一些帶符號(hào)的值:+Infinity,-Infinity 和 NaN (非數(shù)值,Not-a-Number)。
var num1 = 5;
var num2 = NaN;
var num3 = +Infinity;
typeof num1; // "number"
typeof num2; // "number"
typeof num3; // "number"
- String
String 類(lèi)型用于表示由零或多個(gè) 16 位 Unicode 字符組成的字符序列,即字符串。
var name = "jack"
typeof name; // "string"
- Symbol
符號(hào)(Symbols)是ECMAScript 第6版新定義的。符號(hào)類(lèi)型是唯一的并且是不可修改的, 并且也可以用來(lái)作為Object的key的值。
var sym = Symbol("foo");
typeof sym; // "symbol"
復(fù)雜數(shù)據(jù)類(lèi)型:
ECMAScript 中的對(duì)象就是一組數(shù)據(jù)和功能的集合。
var arr = [1, 2, 3];
var o = new Object();
var reg = /\d/g;
var a = {};
typeof arr; // "object"
typeof o; // "object"
typeof reg; // "object"
typeof a; // "object"
因此,可以看出,我們?cè)谂袛嗷緮?shù)據(jù)類(lèi)型時(shí),可以用 typeof 檢測(cè)出來(lái)的,但是對(duì)于復(fù)雜的數(shù)據(jù)類(lèi)型 typeof 就有其局限性了,它對(duì)于復(fù)雜數(shù)據(jù)類(lèi)型總是返回 “object”。
在對(duì)復(fù)雜數(shù)據(jù)類(lèi)型的檢測(cè)中,我們就應(yīng)該用其他方法來(lái)判斷,這就是 instanceof/constructor。
使用 instanceof/constructor 可以檢測(cè)數(shù)組和正則表達(dá)式。
var arr = [1, 2, 3];
var reg = /\d/g;
arr instanceof Array; // true;
reg instanceof RegExp; // true;
arr.constructor == Array; // true;
reg.constructor == RegExp; // true;
嚴(yán)謹(jǐn)?shù)呐袛喾椒ǎ?/p>
function isArray(object){
return object && typeof object==='object' &&
Array == object.constructor;
}
但是,instanceof/constructor 也有其局限性:
被判斷的 Array 必須在當(dāng)前頁(yè)面聲明!
而在父頁(yè)面框架中引用子頁(yè)面,然后在子頁(yè)面中聲明一個(gè) array,并賦值給父頁(yè)面變量,這時(shí)檢測(cè)返回值就是false。
因此,還需要更好的方法來(lái)進(jìn)行檢測(cè),查閱書(shū)籍和網(wǎng)上資料,還用兩種方法:
function isArray(object){
return object && typeof object==='object' &&
typeof object.length==='number' &&
typeof object.splice==='function' &&
//判斷l(xiāng)ength屬性是否是可枚舉的 對(duì)于數(shù)組 將得false
!(object.propertyIsEnumerable('length'));
}
function isArray(o) {
return Object.prototype.toString.call(o) === '[object Array]';
}
參考資料
《JavaScript 高級(jí)程序設(shè)計(jì)》(第三版)
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Data_structures