首頁 >web前端 >js教程 >JavaScript判斷物件的類型

JavaScript判斷物件的類型

高洛峰
高洛峰原創
2016-11-28 11:43:441288瀏覽

總結下來,主要有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();

var objClass = new derobjClass); === derivedClass;//false;

obj.constructor === baseClass;//true;因為子類別的prototype以父類別的實例為原型,所以透過子類別實例存取constructor就是父類別建構子。因此在JavaScript物件導向程式設計中,我們會在定義子類別時加上一句程式碼來修正constructor屬性。

derivedClass.prototype.constructor = derivedClass;使用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 = Object.create(derivedClass.prototype);

obj2 instanceof ClassClass; obj2 instanceof Object;//trueconstructor屬性可以應用到除了null和undefined之外的原始類型(數字、字串、布林類型)。而instanceof不可,但可以使用包裝物件的方法來判斷。


3 instanceof Number // false

'abc' instanceof String // false

true instanceof Boolean // false

new Number(3) instanceof Numberof true

new Boolean(true) instanceof Boolean //true然而,instanceof在cross-frame和cross-window的情況下也無法正常運作。


使用 Object.prototype.toString()方法

Object.prototype.toString()方法是一個底層的方法,使用它可以傳回一個字串,該字串表明了物件的類型。也可以用來判斷null和undefined。下面列出了多數常見的類型。

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"

Any other object "object"


==
// 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!

// Strings

typeof "" === 'string';
typeof "bla" === 'string';
typeof (typeof 1) === 'string'; // typeof always return a string
typeof String("abc") === 'string'; // but never use this form!

// Booleans

type never use this form!

// Booleans
type true === 'boolean';

typeof false === 'boolean';

typeof Boolean(true) === 'boolean'; // but never use this form!

// Undefined

typeof undefined === 'undefined';

typeof blabla === 'undefined'; // an undefined variable

// Objects
typeof {a:1} === 'object';

typeof [1, 2, 4] === 'object'; // use Array.isArray or Object.prototype.toString.call to differentiate regular objects from arrays

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

typeof /s/ === 'object'; // Conform to ECMAScript 5.1typeof 包裝物件的結果是'object'; // Conform to ECMAScript 5.1typeof 包裝物件的結果是'object'需要注意。這裡不評價好與不好(如果需要區分包裝物件和原始類型呢)。但是typeof不是一個健壯的方法,要小心使用。例如:🎜🎜🎜var s = "I am a string";🎜typeof s === "string";🎜//Add a method to String🎜String.prototype.A_String_Method = function(){ . .valueOf());🎜    console.log(typeof this);🎜};🎜s.A_String_Method();🎜//I am a string🎜//object🎜🎜🎜🎜🎜
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn