2010-02-15 133 views
24

所以我有一個需要檢查一個參數是一個對象的功能,但這種失敗,因爲:如何檢查一個對象是不是一個數組?

typeof [] // returns 'object' 

這是一個經典的javascript疑難雜症,但我不記得做實際接受的對象是什麼,但不是數組。

+2

重複:http://stackoverflow.com/questions/1202841/what-is-the-best-way-to-check-if-an-object-is-an-array-或者,未在JavaScript的 – 2010-02-15 12:46:35

回答

30

嘗試這樣:

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

或(甚至更好)

obj instanceof Array 
+0

看來你的第一個建議是最安全的一個,也將解決由下面@Pointy陳述的問題。 謝謝:) – hojberg 2010-02-15 13:04:23

+0

或更精確地說:Object.prototype.toString.call(OBJ)=== '[對象陣列]'; – hojberg 2010-02-15 13:05:39

+1

jQuery有一個實用方法'IsArray的()'。 http://api.jquery.com/jQuery.isArray/ @hojberg我支持你做這件事的方式。jQuery內部也是這樣。 – 2010-02-15 14:12:54

2

您是否嘗試過這樣的:

var test = []; 
if(test instanceof Array) { 
... 
} 

編輯:此方法不起作用在多幀DOM環境中(‘typeof’ considered useless - or how to write robust type checks)。 (via Pointy

+0

不是一個很好的解決方案。見http://juhukinners.com/2009/01/11/typeof-considered-useless-or-how-to-write-robust-type-checks/ – Pointy 2010-02-15 13:07:37

+0

好點。我不知道。 – 2010-02-15 14:07:06

17

所有這些答案都表明,如果對象是「Array」類的實例(即由「Array」構造),則檢查是否看到(以某種方式)安全的方案。他們有時可能會工作,也許大部分時間都在工作,但所有主要框架已經從這種方法中移開。它的主要問題之一是當多個窗口(通常是父窗口和一個或多個框架或iframe窗口)之間存在交互時。如果將在一個窗口中創建的數組對象傳遞到駐留在另一個窗口中的API,則所有這些測試都將失敗。爲什麼?因爲您正在測試的是對象是否是本地窗口上下文中的「Array」類的實例。換句話說,當你在

if (myobject instanceof Array) { ... } 

參考「陣列」什麼你引用是window.Array,當然。那麼,在構造的另一個窗口中的數組是而不是將成爲窗口中的Array類的實例!

檢查構造函數的名稱可能會更安全一些,但它仍然有風險。在我看來,你最好採用鴨子打字的方式。也就是說,不是問,「這是一個數組嗎?」反而問,「這個對象似乎是否支持我在這種情況下需要的一些特定的數組API?」例如,「該對象是否具有length屬性?」 Javascript是一個非常「軟」的語言,幾乎所有的東西都是可變的。因此,即使你確實發現了某些東西是由「陣列」構成的,你仍然不知道你可以用它做什麼或對它做什麼。

[編輯]謝謝你提供的鏈接,@Lachlan - 這裏的問題非常明確的說明:http://juhukinners.com/2009/01/11/typeof-considered-useless-or-how-to-write-robust-type-checks/

+0

+1以獲得很好的解釋。感謝您的支持 – 2010-02-24 16:06:05

3

對於它的價值,這裏是jQuery的檢查東西是否是一個數組:

isArray: function(arr) { 
    return !!arr && arr.constructor == Array; 
} 

但是,this article建議做這樣的:

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

爲了確定一個給定的對象是否是一個數組,ECMAScript的5引入了Array.isArray()方法,目前支持所有現代瀏覽器。請參閱此ECMAScript compatibility table

要確定特定對象的類別,可以使用Object.prototype.toString()方法。

Object.prototype.toString.call({}); // "[object Object]" 
 
Object.prototype.toString.call([]); // "[object Array]"

2

數組是JavaScript對象畢竟,因此,所有你需要做的是檢查變量的類型是一個對象,並在同一時間這個對象不是陣列的實例類。

var obj = {fname:'John',lname:'Doe'}; 

if(typeof obj === 'object' && !(obj instanceof Array)){ 
    return true ; 
} else { 
    return false; 
} 
+0

雖然這可能是一個有效的答案,但您更可能通過解釋代碼的作用和工作方式來幫助他人。僅有代碼的答案往往會得到較少的積極關注,並沒有其他答案那麼有用。 – Aurora0001 2016-11-30 15:02:33

+1

@ Aurora0001可能你是對的,這裏是一個簡單的說明:) – 2016-12-01 08:40:34

0

var obj = {first: 'Stack', last: 'Overflow'}; 
 
// var obj = ['Stack', 'overflow']; //You can uncomment this line and comment the above to check.. 
 

 
if(Object.prototype.toString.call(obj) !== '[object Array]') { 
 
    //your code.. 
 
    var str = ''; 
 
    for(var k in obj) { 
 
    \t str = str + obj[k] + ' '; 
 
    } 
 
    console.log('I love ', str); 
 
    alert('I love ' + str); 
 
} else { 
 
\t console.log('Could not process. Probably an array'); 
 
    alert('Could not process. Probably an array'); 
 
} 
 

 
console.log('Length is: ', Object.keys(obj).length); 
 
alert('Length is: ' + Object.keys(obj).length);
數組

inputArrayObject

要檢查的對象是Array
if(Object.prototype.toString.call(input) === '[object Array]') {}

要檢查的對象是一個Object
if(Object.prototype.toString.call(input) === '[object Object]') {}


請注意Object.keys(input).length將返回長度爲兩數組和對象。

JS Fiddle example爲同一

2

爲了測試某個東西是陣列的一個實例:

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

要測試的東西是一種對象的一個實例:

const obj = { 1: 'a', 2: 'b', 3: 'c' }; 
obj.constructor === Object; // true 

如果objnullundefined,則後者會拋出錯誤,在這種情況下,您可以使用:typeof obj === 'object'或僅執行空值檢查:obj && obj.constructor === Object

1

請使用Object.prototype.toString.call({}).slice(8,-1)==="Object"這適用於所有數據類型,您可以替換調用函數內部的參數,也可以比較以檢查不同的數據類型。它適用於空檢查以及

相關問題