js 判斷數據類型的幾種方式

首先js中的數據類型總的分2類

1.基本數據類型:String、Number、Boolean、Null、Undefined

2.引用類型:Object、Array、Date、Function、Error、RegExp、Math、Number、String、Boolean、Globle。

然後是判斷數據類型的方法:typeof、instanceof、constructor、toString四種常用方法

1.typeof 方法

typeof 返回一個表示數據類型的字符串,返回結果包括:number、boolean、string、object、undefined、function等6種數據類型。

typeof 可以對JS基本數據類型做出準確的判斷(除了null),而對於引用類型返回的基本上都是object, 其實返回object也沒有錯,因爲所有對象的原型鏈最終都指向了Object,Object是所有對象的`祖宗`。 但當我們需要知道某個對象的具體類型時,typeof 就顯得有些力不從心了。

注意:typeof  null會返回object,因爲特殊值null被認爲是一個空的對象引用

          typeof  一個沒有聲明的變量或者聲明沒有初始化的變量都會返回undefined

2、使用instanceof,根據instanceof的定義:判斷參照對象的prototype屬性所指向的對象是否在被行測對象的原型鏈上,這個定義比較繞,舉個栗子:

class Person{
 
   constructor(name){
 
      this.name= name;  
 
   }
 
}
 
  let p = new Person('111')
 
  console.log(p instanceof  Person) //ture

按照定義描述就是Person的prototype屬性所指向的原型對象是否存在於p的原型鏈中。因爲上面Person.prototype = p.__proto__在原型鏈上  所以是true

但是有坑 

    var str = 'hello';
    alert(str instanceof String);//false
    var bool = true;
    alert(bool instanceof Boolean);//false
    var num = 123;
    alert(num instanceof Number);//false
    var nul = null;
    alert(nul instanceof Object);//false
    var und = undefined;
    alert(und instanceof Object);//false
    var oDate = new Date();
    alert(oDate instanceof Date);//true
    var json = {};
    alert(json instanceof Object);//true
    var arr = [];
    alert(arr instanceof Array);//true
    var reg = /a/;
    alert(reg instanceof RegExp);//true
    var fun = function(){};
    alert(fun instanceof Function);//true
    var error = new Error();
    alert(error instanceof Error);//true

從上面的運行結果我們可以看到,基本數據類型是沒有檢測出他們的類型,但是我們使用下面的方式創建num、str、boolean,是可以檢測出類型的:

var num = new Number(123);
var str = new String('abcdef');
var boolean = new Boolean(true);

3、constructor:查看對象對應的構造函數

constructor 在其對應對象的原型下面,是自動生成的。當我們寫一個構造函數的時候,程序會自動添加:構造函數名.prototype.constructor = 構造函數名

function Aaa(){
}
//Aaa.prototype.constructor = Aaa;   //每一個函數都會有的,都是自動生成的
 
//Aaa.prototype.constructor = Aaa;

判斷數據類型的方法

    var str = 'hello';
    alert(str.constructor == String);//true
    var bool = true;
    alert(bool.constructor == Boolean);//true
    var num = 123;
    alert(num.constructor ==Number);//true
   // var nul = null;
   // alert(nul.constructor == Object);//報錯
    //var und = undefined;
    //alert(und.constructor == Object);//報錯
    var oDate = new Date();
    alert(oDate.constructor == Date);//true
    var json = {};
    alert(json.constructor == Object);//true
    var arr = [];
    alert(arr.constructor == Array);//true
    var reg = /a/;
    alert(reg.constructor == RegExp);//true
    var fun = function(){};
    alert(fun.constructor ==Function);//true
    var error = new Error();
    alert(error.constructor == Error);//true

從上面的測試中我們可以看到,undefined和null是不能夠判斷出類型的,並且會報錯。因爲null和undefined是無效的對象,因此是不會有constructor存在的
同時我們也需要注意到的是:使用constructor是不保險的,因爲constructor屬性是可以被修改的,會導致檢測出的結果不正確
 

function Aaa(){
}
Aaa.prototype.constructor = Aaa;//程序可以自動添加,當我們寫個構造函數的時候,程序會自動添加這句代碼
function BBB(){}
Aaa.prototype.constructor = BBB;//此時我們就修改了Aaa構造函數的指向問題
alert(Aaa.construtor==Aaa);//false

可以看出,constructor並沒有正確檢測出正確的構造函數

 

4、Object.prototype.toString(可以說不管是什麼類型,它都可以立即判斷出)

toString是Object原型對象上的一個方法,該方法默認返回其調用者的具體類型,更嚴格的講,是 toString運行時this指向的對象類型, 返回的類型

格式爲[object xxx],xxx是具體的數據類型,其中包括:

String,Number,Boolean,Undefined,Null,Function,Date,Array,RegExp,Error,HTMLDocument,... 基本上所有對象的類型都可以通過這個方法獲取到。 
 

    var str = 'hello';
    console.log(Object.prototype.toString.call(str));//[object String]
    var bool = true;
    console.log(Object.prototype.toString.call(bool))//[object Boolean]
    var num = 123;
    console.log(Object.prototype.toString.call(num));//[object Number]
    var nul = null;
    console.log(Object.prototype.toString.call(nul));//[object Null]
    var und = undefined;
    console.log(Object.prototype.toString.call(und));//[object Undefined]
    var oDate = new Date();
    console.log(Object.prototype.toString.call(oDate));//[object Date]
    var json = {};
    console.log(Object.prototype.toString.call(json));//[object Object]
    var arr = [];
    console.log(Object.prototype.toString.call(arr));//[object Array]
    var reg = /a/;
    console.log(Object.prototype.toString.call(reg));//[object RegExp]
    var fun = function(){};
    console.log(Object.prototype.toString.call(fun));//[object Function]
    var error = new Error();
    console.log(Object.prototype.toString.call(error));//[object Error]

從這個結果也可以看出,不管是什麼類型的,Object.prototype.toString.call();都可以判斷出其具體的類型。

接下來我們分析一下四種方法各自的優缺點

從上表中我們看到了,instanceof和constructor不能跨iframe,上面沒有細說,所以下面我們直接上例子嘍

例:跨頁面判斷是否是數組

window.onload = function(){
	
	var oF = document.createElement('iframe');
	document.body.appendChild( oF );
	
	var ifArray = window.frames[0].Array;
	
	var arr = new ifArray();
	
	//alert( arr.constructor == Array );  //false
	
	//alert( arr instanceof Array );  //false
	
	alert( Object.prototype.toString.call(arr) == '[object Array]' );  //true
	
	
};

從結果中可以看出,constructor和instanceof都沒有正確的判斷出類型,只有object.prototype.toString.call();正確判斷出了

其實面試官也經常喜歡讓說一種最簡單的判斷是數組的方法,記住嘍是object.prototype.toString.call()哦!

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章