1. 程式人生 > >js - 【陣列】怎麼判斷一個變數是陣列型別的?

js - 【陣列】怎麼判斷一個變數是陣列型別的?

怎麼判斷一個數組是陣列呢?

其實這個也是一個常考的題目。依稀記得我為數不多的面試經過中都被問道過。

方案一: instanceof

variable instanceof Array

解決思路:

 使用型別判斷所給的方法 instanceof  進行判斷。

此方法返回一個布林值,能夠精確判斷一個物件的型別。

 

 

方案二:原型prototype + toString  call

Object.prototype.toString.call(variable).indexOf('Array') !== -1;

因為用了toString方法, 返回值是一個字串,還需要第二層判斷,看字串中是否有‘Array’這個關鍵字:

這個字串中有Array關鍵字的返回了數字8(就是Array這個字元在整個"[object Array]"中出現的下標數)。

 

如果變數物件不是一個純陣列,那麼返回的數字就是-1。因為indexOf方法在字串中找不到指定字元就會返回-1.

所以最後還需要通過比對數值是否等於-1就能判斷是否是陣列型別:

true就是了。

 

這裡可能難以理解的是call方法,畢竟前邊toString他們都各司其職。

 首先我們打印出來物件原型上的toString方法返回什麼:

這裡涉及到Object.prototype.toString()的原理。由於我還學的不深入,就不做總結了,

具體可以看這篇總結的不錯:【傳送門

大致意思有:

呼叫toString時會將this物件的[[class]]屬性值拿到,而這個屬性值就是該物件的真實型別。

 

[[class]]:一個內部屬性,字串值,表示物件的型別。只有toString這一個方法可以拿到。

 

而在es5中,toString獲取[[class]]值時需要經過這幾個比較特殊的步驟:

 

總結:

呼叫toString時會將this物件的[[class]]屬性值拿到,而這個屬性值就是該物件的真實型別。

又因為call能夠顯示的修改this指標的物件,所以用call將Object內部的this物件指向我們要檢測的變數自身。

從而再通過toString拿到變數的[[class]]值。

 

方案三:原型prototype + isPrototypeOf()方法

Array.prototype.isPrototypeOf(variable) 

isPrototypeOf() 函式 : 用於指示物件是否存在於一個物件的原型鏈中。如果存在返回true,反之返回false。該方法屬Object物件,由於所有的物件都繼承了Object的物件例項,因此幾乎所有的例項物件都可以使用該方法。

 

所以在上邊程式碼公式中,如果variable的原型鏈中存在Array物件,就會返回true,也就說明variable是陣列型別。

isPrototypeOf的字面意思也就是a是不是b的原型。

看上圖就知道了,Array就是變數m的原型。所以用這個方法就能判斷出來。

對比一個型別為“純”Object的變數打印出來的資訊:

就更加一目瞭然為什麼用這個方法就可以判斷出來了吧!

 

 

 

方案四:建構函式 constructor

variable.constructor.toString().indexOf("Array") !== -1

這個一圖勝千言:

 

對比變數a的列印資訊,可以看出來,一個數組型別的例項,其原型__proto__.constructor右邊是Array關鍵字。

所以我們可以用這個關鍵點拿到也給字串:

然後用方案二的原理差不多的,我們查詢字串中Array關鍵字的位置是否等於-1。即能得出變數是否為陣列型別得了。

 

 

方案五:陣列方法 isArray()

Array.isArray(variable);

思路:

js的一個方法,專門用來測試物件是否是Array型別

 在方案一、二、三的基礎上,可以總結整理這個isArray的內部原理

然後把方案1234自己封裝成isArray()函式。(待做)

 

 

2018-11-19  21:06:57