判斷一個對象是否是數組,有幾種辦法?

這是一個出現過無數次的話題,這裏再次重寫僅做爲我的的學習筆記,謝謝觀看。es6

0、typeof

typeof 運算符的主要做用就是用來檢測數據的類型,通常狀況下咱們都是使用它來判斷數據類型,可是這裏,我把typeof 放在0的位置,由於 typeof 不能檢測到數組類型!typeof 所能識別的類型只有原始類型(Undefined,Null,Boolean,Number,String,Symbol )以及 function 和 object。數組

須要注意的是null,null所檢測出來的結果是"object",由於在js中,null除了做爲空引用的存在,它也是對象整個原型鏈上最頂端的存在,即app

Object.prototype.__proto__ === null;//true

其餘使用typeof的場景:函數

// Numbers
typeof 3.14 === 'number';
typeof Math.LN2 === 'number'; 
typeof Infinity === 'number'; 
typeof NaN === 'number'; //儘管NaN是"Not-A-Number"的縮寫

// Strings
typeof "bla" === 'string'; 
typeof (typeof 1) === 'string'; //typeof老是返回一個字符串

// Booleans
typeof true === 'boolean';

// Symbols
typeof Symbol() === 'symbol';
typeof Symbol.iterator === 'symbol';

// Undefined
typeof undefined === 'undefined';

// null
typeof null === 'object';//從一開始出現JavaScript就是這樣的

// function
typeof function(){} === 'function';
typeof class C{} === 'function'

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

// 下面的結果是什麼?
typeof new Boolean(true) === 'object';
typeof new Number(1) === 'object';
typeof new String("abc") === 'object';
//new 所建立的都是對象,賦值給變量是執行了內部valueOf()或者toString()函數

最後,typeof不能檢測到數組類型!學習

一、驗證原型對象:

從原型鏈上尋找(認祖歸宗)prototype

一、Object.getPrototypeOf(obj) == Array.prototypecode

getPrototypeOf: 這是Object自帶的一個API,做用是獲取一個對象的原型對象對象

二、var bool = Array.prototype.isPrototypeOf(obj)繼承

每一個對象都有一個isPrototypeOf的API,繼承自Object.prototype,用來 判斷father(Array)是不是child(obj)的父對象ip

二、驗證構造函數:

從構造函數上判斷(它的親孃)

一、obj.constructor == Array

構造函數的prototype指向原型對象,同時,原型對象有constructor指回構造函數對象,constructor只在原型對象上有

二、var bool = obj instanceof Array

instance: 判斷對象(obj)是否由構造函數(Array)建立出來

這種方法有一個問題,就是驗證不夠嚴格。 即便對象建立時不是使用數組建立的,可是隻要原型鏈上有數組類型,也認爲是數組,以下面一段代碼:

function Test(){}
Test.prototype = Array.prototype;
let test = new Test();
test instanceof Array;//true

三、檢查內部屬性class + call或apply:

這個class不是es6中對象聲明的class

這個class是每一個對象中記錄對象建立時使用的類型的屬性,一旦對象被建立,class屬性就沒法被修改!

得到class的惟一的辦法就是調用Object.prototype中的toString()方法

輸出結果有"[object Object]","[object Function]"等

問題: 幾乎全部內置對象的原型對象都重寫了Object中的toString方法,全部內置對象的子對象,都沒法直接調到Object的toString。

let arr = [1];
arr.toString();//"1"
let date = new Date();
date.toString();//"Wed Mar 07 2018 16:22:16 GMT+0800 (中國標準時間)"

雖然直接使用不行,可是咱們能夠利用js的call和apply函數來解決這個問題

Object.prototype.toString.call(obj)=="[object Array]"

使用這個方法判斷其餘類型:

console.log(Object.prototype.toString.call("jerry"));//[object String]
console.log(Object.prototype.toString.call(12));//[object Number]
console.log(Object.prototype.toString.call(true));//[object Boolean]
console.log(Object.prototype.toString.call(undefined));//[object Undefined]
console.log(Object.prototype.toString.call(null));//[object Null]
console.log(Object.prototype.toString.call({name: "jerry"}));//[object Object]
console.log(Object.prototype.toString.call(function(){}));//[object Function]
console.log(Object.prototype.toString.call([]));//[object Array]
console.log(Object.prototype.toString.call(new Date));//[object Date]
console.log(Object.prototype.toString.call(/\d/));//[object RegExp]
function Person(){};
console.log(Object.prototype.toString.call(new Person));//[object Object]

四、ES5中的API:Array.isArray(obj)

這是ES5出的一個API,專門用來判斷一個對象是否是數組的,因此,看到這裏有沒有感受前面都白看了....

他的用法也很簡單:

var arr = [1,2,3,4];
Array.isArray(arr);//true

寫在最後

若是文中有什麼錯誤的地方,還請你們給予指出,另外你們若是還有什麼別的方法的話,也能夠在評論區寫下或私信我,你們集思廣益,相互學習,共同進步。

相關文章
相關標籤/搜索