前端之路 — JavaScript 準確判斷數據類型的方法

JavaScript 中常見的幾種數據類型:javascript

基本類型:string,number,boolean,Symbolhtml

特殊類型:undefined,nullvue

引用類型:Object,Function,Function,Array,Date,...java


一、typeofvue-router

typeof '';               // string 有效
typeof 1;                // number 有效
typeof true;             // boolean 有效
typeof undefined;        // undefined 有效
typeof null;             // object 無效
typeof [] ;              // object 無效
typeof new Function();   // function 有效
typeof new Date();       // object 無效
typeof new RegExp();     // object 無效
複製代碼

JavaScript 裏 使用 typeof 來判斷數據類型,只能區分基本類型,即 「 number 」 , 「 string 」 , 「 undefined 」 , 「 boolean 」 , 「 object 」 五種。數組

對於數組、函數、對象來講,其關係錯綜複雜,使用 typeof 都會統一返回 「object」 字符串。瀏覽器

因此,要想區別對象、數組、函數單純使用 typeof 是不行的 ,JavaScript 中,經過 Object.prototype.toString 方法,判斷某個對象值屬於哪一種內置類型。markdown


二、Object.prototype.toString$.type()網絡

console.log(Object.prototype.toString.call(123))          // [object Number]
console.log(Object.prototype.toString.call('123'))        // [object String]
console.log(Object.prototype.toString.call(undefined))    // [object Undefined]
console.log(Object.prototype.toString.call(true))         // [object Boolean]
console.log(Object.prototype.toString.call({}))           // [object Object]
console.log(Object.prototype.toString.call([]))           // [object Array]
console.log(Object.prototype.toString.call(function(){})) // [object Function]
console.log(Object.prototype.toString.call(this));        // [object Window]
複製代碼

判斷是否爲函數:函數

function isFunction(it) {
    return Object.prototype.toString.call(it) === '[object Function]';
}
複製代碼

判斷是否爲數組:

function isArray(o) { 
    return Object.prototype.toString.call(o) === '[object Array]';  
}
複製代碼

到這裏不得不說 Object.prototype.toString.call() 真是判斷數據類型的**"萬精油"**呀!(絕招不必定要放在最後/doge/)

在 Object.prototype.toString 方法被調用時,會執行下面的操做步驟(瞭解):

  1. 獲取this對象的[[Class]]屬性的值。

  2. 計算出三個字符串"[object ", 第一步的操做結果Result(1), 以及 "]"鏈接後的新字符串.

  3. 返回第二步的操做結果Result(2)。

[[Class]]是一個內部屬性,全部的對象(原生對象和宿主對象)都擁有該屬性。在規範中,[[Class]]是這麼定義的:

內部屬性 描述
[[Class]] 一個字符串值,代表了該對象的類型。

重點: [[Class]] 代表了該對象的類型

讀到這裏,你就已經掌握了準確判斷數據類型的方法了,是否是感受本身有進步了呢。

或許你用過 jQuery 的 $.type() 方法判斷數據類型,其實它就是對 Object.prototype.toString.call() 的一個封裝,還有在 vue-router 的源碼等地方里也用來轉換和檢測數據類型。


固然,判斷數據類型不止於以上這3種方法(typeof,Object.prototype.toString,$.type()),還有 instanceof 和 constructor 進行數據類型判斷,不過他們都存在一些缺點。

三、instanceof

console.log(2 instanceof Number);                    // false
console.log(true instanceof Boolean);                // false 
console.log('str' instanceof String);                // false 
console.log([] instanceof Array);                    // true
console.log(function(){} instanceof Function);       // true
console.log({} instanceof Object);                   // true

// 這倆比較特殊,稍做解釋
// console.log(undefined instanceof Undefined);
// console.log(null instanceof Null);
複製代碼

以上結果顯示,直接的字面量值判斷數據類型,只有引用數據類型(Array,Function,Object)被精準判斷,其餘(數值Number,布爾值Boolean,字符串String)字面值不能被instanceof精準判斷。

咱們來看一下 instanceof 在 MDN 中的解釋:instanceof 運算符用來測試一個對象在其原型鏈中是否存在一個構造函數的 prototype 屬性。其意思就是判斷對象是不是某一數據類型(如Array)的實例,請重點關注一下是判斷一個對象是不是數據類型的實例。在這裏字面量值,2, true ,'str'不是實例,因此判斷值爲false。眼見爲實,看下面的例子:

console.log(new Number(2) instanceof Number)      // true
console.log(new Boolean(true) instanceof Boolean) // true
console.log(new String('str') instanceof String)  // true
複製代碼

字面值被實例化了,他們的判斷值變爲了 true 。

接着,咱們看一下 undefined 和 null ,說說爲何這兩貨比較特殊,實際上按理來講,null的所屬類就是Null,undefined就是Undefined,但事實並不是如此。控制檯輸出以下結果:

console.log(new undefined instanceof Undefined)
// TypeError: undefined is not a constructor
console.log(new null instanceof Null)
// TypeError: null is not a constructor
複製代碼

瀏覽器認爲null,undefined不是構造器。可是在 typeof 中你可能已經發現了,typeof null的結果是object,typeof undefined的結果是undefined ,這是怎麼回事呢 ? 其實這是 JavaScript 設計者的一大重大失誤, Google公司開發的JavaScript語言的替代品Dart語言,就明確規定只有null,沒有undefined!

想了解 undefined 和 null 的區別 能夠看下 阮一峯大神的網絡日誌: www.ruanyifeng.com/blog/2014/0…


四、constructor

console.log((2).constructor === Number);                // true
console.log((true).constructor === Boolean);            // true
console.log(('str').constructor === String);            // true
console.log(([]).constructor === Array);                // true
console.log((function() {}).constructor === Function);  // true
console.log(({}).constructor === Object);               // true
複製代碼

用costructor來判斷類型看起來是完美的,然而,若是我建立一個對象,更改它的原型,這種方式也變得不可靠了。

function Fn(){};
 
Fn.prototype = new Array();

var f = new Fn();
console.log(f.constructor === Fn);    // false
console.log(f.constructor === Array); // true

複製代碼

如此輕易的更改了contructor,說明了什麼, Object.prototype.toString.call() 真香,/doge/。

以上就是我對 JavaScript 數據類型判斷的一個學習總結了,你們加油!

ps:廣州有坑位請聯繫我郵箱 2412684394@qq.com ,歡迎騷擾。

相關文章
相關標籤/搜索