0%

JavaScript 判別是否為陣列 Array 的方法

陣列在 JS 裡的原生型別是 object,這點可以由 typeof 來確認。但如果要確認某一元素的原型是陣列,或是在物件裡的某一元素是陣列,又該怎麼判別?
如果元素不是陣列,就無法使用陣列專用的函式或做些陣列的處理,因此才會有確認某元素的原型是陣列的需求。

1.isArray

最簡單的陣列判斷語法 isArray,用的是內建 Array 物件中的 isArray,是個 ES5 的標準方法:
Array.isArray(variable)

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

使用constructor,這是在 Chrome 瀏覽器中效能最佳的判斷方法,它是直接用物件的建構式來判斷:
variable.constructor === Array

1
2
var a = [1, '2', [3, 4, 5]];
a.constructor === Array; // true

判別物件中的陣列

3.constructor === Array

如果要判別物件中的其中屬性是否為陣列,可以先判斷這個屬性是否存在,如下(foo 指的是物件屬性):
variable.foo && variable.foo.constructor === Array

1
2
3
4
5
6
7
8
9
var b = {
foo: [1, 2, 'f'],
ho: [2, 3, 4],
hi: 'hello'
};

b.foo && b.foo.constructor === Array; // true
b.ho && b.ho.constructor === Array; // true
b.hi && b.hi.constructor === Array; // false

例外: 當使用在一個繼承自陣列的陣列會失效

4.instanceof

instanceof 也是用物件的相關判別方法來判斷,instanceof 運算符是用於判斷是否為某個物件的實例,優點為語法簡潔清楚。

1
2
3
4
5
6
7
8
9
var a = [1, 2, 3];
a instanceof Array; // true

var oArrayObject = new Array([1, 2, 3]);
oArrayObject instanceof Array; // true

// 也適用於其他型別的判別
var oStringObject = new String('hello world');
oStringObject instanceof String; // true

例外: 處理不同 window 或 iframe 時的變數會失效

5.toString.call

==推薦使用==
網路上推薦這種方式判別的頗多,原因應該是這種方式是所有情況都可以正確判斷的一種,且可適用各種狀況,也可以判斷陣列以外的其他特別物件,唯一缺點是效率最差。

1
Object.prototype.toString.call(variable) === '[object Array]';

據說在 JavaScript: The Definitive Guide, 6th Edition 書中有提到,Array.isArray 其實就是用這個方式實作的。

另外,網路上也有人寫成一支判斷陣列終極解決方案:

1
2
3
4
5
6
7
8
9
10
11
var arr = [1, 2, 3];
function isArrayFn(obj) {
// 包成函式
if (typeof Array.isArray === 'function') {
return Array.isArray(obj); // 如果瀏覽器支援就用 isArray() 方法
} else {
// 否則就使用 toString 方法
return Object.prototype.toString.call(obj) === '[object Array]';
}
}
isArrayFn(arr); // true

用哪一種?

這幾個方式的選擇,網路上的前輩建議是==只要學最後一種==就行了(如果不考慮舊瀏覽器就用第一種),它可以正確判斷並應用在各種情況,有時候正確比效能快更為重要,更何況它其實是萬用的,除了陣列之外也可以用於其它的判斷情況。雖然它的語法對初學者來說,可能無法在此時完全理解,不過就先知道要這樣用就行了。