總結下來,主要有constructor屬性、typeof運算子、instanceof運算子和Object.prototype.toString()方法這四個方式來判斷物件的型別。
constructor屬性
建構子預先定義的constructor屬性是建構子本身。
var Foo = function(){};
Foo.prototype.constructor === Foo;//true透過new呼叫建構函式所產生的物件以建構函式的prototype屬性為原型。雖然JavaScript中沒有類別的概念,但是建構函數的作用同類的名稱相似,是物件類型的識別。存取物件繼承的constructor屬性可以查看物件的類型。原始類型的變數也可以存取constructor屬性,因為在存取的時候JavaScript形成了一個包裝物件。
1 //basic objects
2 var obj = {name: "obj"};
3 obj.constructor === Object;//true
4
5 // //f defined function(){};
7 var f = new Foo();
8 f.constructor === Foo;//true
9
10 //primitive types
11 //Number
12 var num = 1;
13 num.constructor === Number;//true
14 var nan = NaN;
15 nan.constructor === Number;//true
16 //Boolean
17 var b = true;
18 b.constructor = == Boolean;//true
19 //String
20 var s = "string";
21 s.constructor === String;//true
22 //Function
23 var Fun =function(){};
24 Fun.constructor === Function;//true;然而,constructor屬性是可以重新複製或覆蓋的,這會造成類型判斷的錯誤。即使我們一般不會刻意去給constructor屬性賦值,但是有些情況下constructor屬性的值和我們所期望的值不同。看下面範例:
var baseClass = function(){};
var derivedClass = function(){};
derivedClass.prototype = new baseClass();
obj.constructor === baseClass;//true;因為子類別的prototype以父類別的實例為原型,所以透過子類別實例存取constructor就是父類別建構子。因此在JavaScript物件導向程式設計中,我們會在定義子類別時加上一句程式碼來修正constructor屬性。
cross-frame和cross-window問題:
如果判斷來自不同frame或來自不同window的變數的物件的類型,那麼constructor屬性無法正常運作。因為不同window的核心類型不同[1]。
使用instanceof操作子
instanceof操作符判斷一個物件的原型鏈中是否存在某個建構子的prototype屬性[2]。原型鏈的概念可以閱讀JavaScript物件導向程式設計(一)原型與繼承。下面的程式碼形成了原型鏈obj1->derivedClass.prototype->baseClass.prototype->...->Object.prototype。 Object.prototype是所有物件的原型,anyObj instanceof Object === true。
var baseClass = function(){};var derivedClass = function(){};
derivedClass.prototype = new Class();//use inheritance
var obj1Class();//use inheritance
var obj1Class = 105%)d ;//true
obj1 instanceof derivedClass;//true
obj1 instanceof Object;//true
obj2 instanceof ClassClass; obj2 instanceof Object;//trueconstructor屬性可以應用到除了null和undefined之外的原始類型(數字、字串、布林類型)。而instanceof不可,但可以使用包裝物件的方法來判斷。
3 instanceof Number // false
true instanceof Boolean // false
new Number(3) instanceof Numberof true
使用 Object.prototype.toString()方法
Object.prototype.toString.call(3);//"[object Number]"
Object.prototype.toString.call(NaN);//"[object Number]"Object.prototype.toString.call ([1,2,3]);//"[object Array]"
Object.prototype.toString.call(true);//"[object Boolean]"
Object.prototype.toString.call("abc" );//"[object String]"
Object.prototype.toString.call(/[a-z]/);//"[object RegExp]"
Object.prototype.toString.call(function(){}); //"[object Function]"
//null and undefined in Chrome and Firefox. In IE "[object Object]"
Object.prototype.toString.call(null);//"[object Null]"
Object.prototype.toString.call(undefined) ;//"[object Undefined]"
//self defined Objects
var a = new Foo();
Object.prototype.toString.call(a);//"[object Object]"
//Typed Wrappers
var b = new Boolean(true);
Object.prototype.toString.call(b);//"[object Boolean]"
var n = new Number(1);
Object.prototype.toString.call( n);//"[object Number]"
var s = new String("abc");
Object.prototype.toString.call(s);//"[object String]"常會使用slice方法截取結果中類型的資訊:
Object.prototype.toString.call("abc").slice(8,-1);//"String"使用typeof 運算子
在MDN的一篇文件中已經很詳細介紹了這個[3]。 typeof能回傳的資訊較少,有"undefined"、"object"、"boolean"、"number"、"string"、"function"、"xml"這幾種。
Type Result
Undefined "undefined"
Null "object"
Boolean "boolean"
Number "number"
String "string"
Host object (provided by"
String "string"
Host object (provided by the JS enlments. ]] in ECMA-262 terms) "function"
E4X XML object "xml"
E4X XMLList object "xml"
==
// Numberstypen 3. 3.14 === 'number';
typeof Math.LN2 === 'number';
typeof Infinity === 'number';
typeof NaN === 'number'; // Despite being "Not-A-Number "
typeof Number(1) === 'number'; // but never use this form!
typeof "" === 'string';
typeof "bla" === 'string';
typeof (typeof 1) === 'string'; // typeof always return a string
typeof String("abc") === 'string'; // but never use this form!
type never use this form!
// Booleans
type true === 'boolean';
typeof Boolean(true) === 'boolean'; // but never use this form!
// Undefined
typeof blabla === 'undefined'; // an undefined variable
// Objects
typeof {a:1} === 'object';
typeof new Date() === 'object';
typeof new Boolean(true) === 'object';
typeof new Boolean(true) === 'object'; '; // this is confusing. Don't use!
typeof new Number(1) === 'object'; // this is confusing. Don't use!
typeof new String("abc") === 'object'; // this is confusing. Don't use!
// Functions
typeof function(){} === 'function';
typeof Math.sin === 'function';
typeof Math.sin === 'function';
typeof Math.sin === 'function';
typeof Math.sin === 'function';
typeof Math.sin === 'function';
typeof Math。 undefined;//"undefined"
typeof null;//"object" This stands since the beginning of JavaScript