JS檢測數據類型的四種方式

檢測宗旨

對一些不確定的值操作時,為了避免發生錯誤,最穩妥的方式是在操作之前要加一個數據類型判斷,再根據相應類型來進行不同的操作。

比如回調函數

function fn(callBack) { callBack();}

這個時候就要在callBack執行之前加一個是否為函數的判斷,如果是再讓函數執行

修改如下

function fn(callBack) { if(typeof callBack === function) { callBack(); }}

在檢測一些引用數據類型的時候,我們更想知道這個對象是屬於哪個類,比如想判斷一個對象是否為數組,好去調用數組上的方法,而不是想判斷這個對象是不是屬於對象。因為數組的方法都是保存在數組的原型上,而不是在Object基類上。

檢測方法

typeof

用法

typeof是一個操作符

在執行的時候可以typeof(要檢測的對象);

也可以這樣typeof 要檢測的對象,因為typeof不是函數,因此()不是必需的,可以將檢測的對象直接跟在typeof後面

檢測範圍

在JS中,能用typeof能檢測出來的數據類型,最好使用typeof來檢測

typeof是基本數據類型檢測利器(但是不包括null);也可以檢測是否為一個函數,但是在檢測對象時,並不能為每個對象明確指出是屬於哪一類,因為返回值都是object。

示例

typeof 1;//numbertypeof true;//booleantypeof ;//stringtypeof undefined;//undefinedtypeof function (){};function

tips

typeof的返回值是一個字元串,有時候在瀏覽器里會把引號省略掉,但是可以用typeof去檢測這個返回值,比如

typeof typeof 1;//string//這行代碼的意思是,用typeof去檢測typeof 1的返回值,最終的返回值是string

因為這個也以引伸,如果兩個及以上的typeof連用的話,那麼輸出的結果就是string

typeof null

null在JS中叫做空對象指針,因此可以理解為null為對象

而更專業的解釋是

JS類型值是存在32 BIT 單元里,32位有1-3位表示TYPE TAG,其它位表示真實值 而表示object的標記位正好是低三位都是0 000: object. The data is a reference to an object. 而js 里的Null 是機器碼NULL空指針, (0x00 is most platforms).所以空指針引用 加上 對象標記還是0,最終體現的類型還是object..

instanceof

用法

instanceof是一個操作符,返回值是一個布爾值

instanceof是檢測引用數據類型,而不能檢測基本數據類型

var arr = [];arr instanceof Array;//true

但是只要是在原型鏈上出現過構造函數都會返回true,所以這個檢測結果不很準確

arr instanceof Object;//true

constructor

constructor這個屬性存在於構造函數的原型上,指向構造函數,對象可以通過__proto__在其所屬類的原型上找到這個屬性

var arr = [];arr.constructor === Array;//truearr.constructor === Object;//false//因為arr通過原型鏈查找到的constructor指向了Array,所以跟Object判斷就是錯誤滴

constructor是比較準確判斷對象的所屬類型的,但是如果有繼承的話

function Fn() {}Fn.prototype = new Array();var fn = new Fn();console.log(fn.constructor === Array);//fn是一個對象,但是它的構造函數指向Array竟然是true

因此這個方法要慎用

Object.prototype.toString.call()

在Object基本類定義的這個toString()方法,是用來檢測數據類型的;

跟字元串、數字、布爾等原型上定義的toString()方法基本用法都是轉換字元串的。

這對對數據檢測應該是最準確的

console.log(Object.prototype.toString.call(1));//[object Number]console.log(Object.prototype.toString.call());//[object String]console.log(Object.prototype.toString.call(true));//[object Boolean]console.log(Object.prototype.toString.call(null));// [object Null]console.log(Object.prototype.toString.call(undefined));//[object Undefined]console.log(Object.prototype.toString.call([]));// [object Array]console.log(Object.prototype.toString.call({}));// [object Object]console.log(Object.prototype.toString.call(/^$/));//[object RegExp]console.log(Object.prototype.toString.call((function () {})));//[object Function]

基本包裝類型

JS是一門弱類型的語言,因此在定義變數時,一般都可以使用字面量方式和實例創建方式。

一般兩種創建方式沒有差別,但是涉及到基本數據類型中的number、string、boolean時就完成不一樣。

例如

var a = 1;var b = new Number(1);typeof a;//numbertypeof b;//object

因為字面創建基本數據類型的值時,並不會調用JS的內置構造函數,因此字面量創建的值就是基本數據類型,而不是實例(對象數據類型)。-->所以用instanceof檢測基本數據類型時都會返回false

但是一個基本數據類型並不是對象,是不應該有屬性的,但是給一個字元串添加一個屬性時,也不會報錯,在讀取屬性時,也什麼也讀取不到。

var str = chang;str.name = joo;console.log(str.name);//undefined

這是因為,在JS中有三種基本包裝類型,Nmber,String,Boolean

例如一個字元串,當作對象去調用其原型上的方法時,JS會臨時創建一個與其對應的基本包裝類型的值,這個值是String的實例,調用方法,其實是這個實例在調用字元串的方法。

var str = chang;str.split();//代碼執行到這行時,會臨時創建與str等價的對象,去調用字元串的方法

這個臨時創建的對象的生命周期,只有在調用方法的一瞬間,調用完成後就隨即銷毀了。因此上例在給字元串添加屬性時不會報錯,在讀取時也讀不到銷毀的字元串,因此讀取時返回undefined。

這樣,在用constructor檢測數據類型時

var str = chang;str.constructor === String;//true

檢測的其實是臨時創建的基本包裝類型的對象


推薦閱讀:

互聯網如何助力物流模式加速進化?
2016中國互聯網大會 |【友盟+】COO葉謙:全域數據智能未來
4 · 網大 |做網路大電影,這些事兒你必須知道!
互聯網+還是+互聯網
如何看待17173垂直遊戲媒體的「深耕」與「播種」?

TAG:互聯網 | 前端開發 |