1. 語(yǔ)言類型
JavaScript定義了7種語(yǔ)言類型:
Undefined, Null, Boolean, String, Number, Symbol, Object梳码。
圍繞Object尤莺,又有很多特殊的類型:
Date, RegExp, Function。
2. 類型判斷
undefined
Undefined類型表示未經(jīng)賦值的”空值“备埃,該類型只有一個(gè)值,可以用全局變量undefined來(lái)表示未状。使用 variable === undefined 或者 variable === void 0 可以判斷一個(gè)值是否為該類型鸭限,后者在ES5之前更可靠因?yàn)槟菚r(shí)的全局變量undefined是可以被更改的蜕径。
null
Null類型只有一個(gè)值,那就是null败京,它是JavaScript的關(guān)鍵字兜喻,可以直接用null來(lái)判定值 variable === null。
Boolean, String, Number
這里的數(shù)字赡麦、字符串朴皆、布爾類型是可以是原始類型,也可以它們的包裝對(duì)象泛粹。簡(jiǎn)單通過如下代碼即可進(jìn)行類型判定:
typeof num === 'number'
typeof str === 'string'
typeof bol === 'boolean'
比較特殊的一點(diǎn)是typeof null 得到的是 object涣达,可以把它當(dāng)做一個(gè)”非對(duì)象“類型的對(duì)象缆镣。
Symbol
同樣可以直接使用 typeof 判斷Symbol類型
typeof sy === 'symbol'
Object
JavaScript是面向?qū)ο蟮木幊陶Z(yǔ)言蔫骂,在開發(fā)過程中會(huì)用到大量的對(duì)象魁巩,僅僅使用 typeof 顯然無(wú)助于了解更多跟對(duì)象相關(guān)的信息
我們可以使用 Object.prototype.toString.apply(variable)
會(huì)返回類似于 [object Object]
的結(jié)構(gòu),第二個(gè)Object
會(huì)隨著構(gòu)造函數(shù)的不同而不同帽借。
因此我們就可以使用如下代碼來(lái)判斷具體的類型:
Object.prototype.toString.apply(o).slice(8, -1) === 'Object'
Object.prototype.toString.apply(n).slice(8, -1) === 'Number'
Object.prototype.toString.apply(s).slice(8, -1) === 'String'
Object.prototype.toString.apply(b).slice(8, -1) === 'Boolean'
Object.prototype.toString.apply(d).slice(8, -1) === 'Date'
Object.prototype.toString.apply(r).slice(8, -1) === 'RegExp'
Object.prototype.toString.apply(r).slice(8, -1) === 'Function'
Object.prototype.toString.apply(c).slice(8, -1) === 'CustomClass'
3. 其他相關(guān)方法
instanceOf運(yùn)算符
該運(yùn)算符期望左操作數(shù)是對(duì)象珠增,右操作符是表示對(duì)象的類, 因?yàn)樗械膶?duì)象都是Object的實(shí)例砍艾,所以判斷一個(gè)對(duì)象是否是一個(gè)類的實(shí)例的時(shí)候蒂教,所有對(duì)該類的"父類"的檢測(cè)也能通過。
var d = new Date();
d instanceof Date; //true
d instanceof Object; //true
為什么不能直接使用instanceOf作為類型檢測(cè)脆荷?原因是Web瀏覽器可能有多個(gè)窗口或者frame存在凝垛,每個(gè)窗口都有自己的JavaScript環(huán)境,都有自己的全局對(duì)象蜓谋,因此一個(gè)窗體中的對(duì)象將不是另外窗體的的構(gòu)造函數(shù)的實(shí)例梦皮。
isPrototypeOf
JavaScript希望將原型對(duì)象作為類的唯一標(biāo)志,例如桃焕,如下的Cat的實(shí)例可以通過isPrototypeOf的方法來(lái)判定它是否是屬于Cat類:
function Cat(){}
var cat = new Cat();
Cat.prototype.isPrototypeOf(cat);
使用constructor.prototype判斷為什么不可靠
創(chuàng)建對(duì)象有三種方法中剑肯,分別是
(1)對(duì)象直接量, var o = {};
(2)通過new观堂,var Cat=function(){} var c = new Cat();
(3)通過Object.create让网,Object.create({})
其中(2)(3)想要通過constructor.prototype來(lái)判定對(duì)象所屬類是不可靠的,舉例:
function F(){};
F.prototype = {y: 1};
var o = new F();
o.constructor.prototype === F.prototype; // false
o.constructor.prototype === Object.prototype; // true
F.prototype.isPrototypeOf(o); // true
var p = {x:1};
var o2 = Object.create(p);
o2.constructor.prototype === p; // false
o2.constructor.prototype === Object.prototype; // true
p.isPrototypeOf(o2); // true
初始化對(duì)象的constructor則不能作為類的標(biāo)志师痕,因?yàn)閮蓚€(gè)不同個(gè)構(gòu)造函數(shù)的prototype屬性可能指向同一個(gè)原型對(duì)象溃睹。但因?yàn)闃?gòu)造函數(shù)的”外在表現(xiàn)“,它的名字常被用作類名胰坟,而且instanceOf的表現(xiàn)強(qiáng)化了”構(gòu)造函數(shù)是類的共有標(biāo)志“的印象因篇。
NaN
NaN === NaN // false
isNaN(NaN) // true
4. 使用總結(jié)
is null: val === null
is undefiend: val === undefined
is boolean: typeof val === 'boolean'
is string: typeof val === 'string'
is number: typeof val === 'number'
is object: Object.prototype.toString.apply(val).slice(8, -1) === 'Object'
is date: Object.prototype.toString.apply(val).slice(8, -1) === 'Date'
is array: Object.prototype.toString.apply(val).slice(8, -1) === 'Array'