Javascript中數組的判斷方法
摘要:
1.數組檢測的方法:
1) typeof 、
2) instanceof 、
3) constructor 、
4) Object.prototype.toString、
5) Array.isArray()。
以上為數組檢測的方法,但是這些方法中:
Array.isArray()方法是最為簡單方便的方法,但是存在版本支持性問題,沒有版本支持性問題且較好的檢測方法是使用Object.prototype.toString結合call()方法來檢查,通常數組檢測中我們常用的做法是兩種方法結合。
原型鏈,在使用數組檢測方法時我們要對原型鏈有深刻的理解,才能知道使用該數組檢測方法的實際原理是什麽。關於原型鏈的理解,可以看我寫的這篇博客:http://www.cnblogs.com/novice007/p/7764583.html
構造函數,使用構造函數的方法檢測數組,這是很大的一個坑,因為構造函數是能夠被重寫的,所以所得結果就不正確。例如:
1)var arr = [];
arr.constructor === Array; //返回true
2)var arr = ‘abc‘;
arr.constructor = Array;
arr.constructor === Array; //返回true
因為constructor能夠被重寫,所以從例2可以很明顯的知道arr不是數組,但是它被數組重寫了,所以返回true。
方法簡介
1.typeof方法
typeof方法是判斷數據的類型。在JavaScript中基本數據類型有
1)字符串(string),typeof()的返回值為string,例如typeof(‘97900’)==》返回string。
2)函數類型(function),typeof()的返回值為function,例如typeof(RegExp)==》返回function。
3)數組(array)、對象(object)、null,typeof()的返回值都為object,例如typeof(null)、typeof(document),typeof([1,3,4,8])==》返回object。
4)布爾類型(Boolean),typeof()的返回值為Boolean,例如typeof(true)==》返回Boolean。
5)數字類型,typeof()的返回值為number,例如typeof(1)==》返回number。
6)對於未定義的變量,typeof()檢測結果都返回undefined。
說明:由上面typeof方法對各個數據類型的檢測返回值可知typeof方法不能夠準確的檢測一個數據是否是數組,因為typeof方法對對象、數組、null的檢測結果都是返回object,我們並不能夠知道該數據是否為對象還是數組。從中我們也可以得知在使用 typeof 運算符時采用引用類型存儲值會有一些問題,就是不管引用的是什麽類型的對象,它都返回 “object”。
2.instanceof方法
instanceof方法是用來判斷一個對象是否是當前類的一個實例,也可以在繼承關系中用來判斷一個實例是否屬於它的父類型,返回值為true或false。如下例子:
1)console.log(Object instanceof Object);//true
console.log(Function instanceof Function);//true
console.log(Number instanceof Number);//false
console.log(String instanceof String);//false
console.log(Function instanceof Object);//true
2)instanceof方法在繼承關系中用來判斷一個實例是否屬於它的父類型。
function A(){}
function B(){}
B.prototype = new A();//JavaScript 原型繼承
var C = new B();
console.log(C instanceof B)//true
console.log(C instanceof A)//true
說明:這裏大家可能比較好奇,為什麽只有Object和function的instanceof返回值為true,其它的(a instanceof a)返回值都為false,對於這個問題,大家可以在https://www.ibm.com/developerworks/cn/web/1306_jiangjj_
jsinstanceof/這篇文章中看看,這篇文章中對instanceof的用法講解的非常的清楚,這裏我就不再說明。Instanceof用法用法很強大,但是instanceof也不是判斷數組的好方法,原因我們再通過下面這個例子說明一下:
window.onload=function(){
Var iframe_arr=new window.frames[0].Array;
alert(iframe_arrinstanceof Array); //返回 false
}
出現這個問題的原因簡單的說是因為在不同框架(iframe)中創建的數組不會相互共享其prototype屬性。
原型鏈:
ECMAScript中對原型鏈的概念進行了描述,通過查閱了ECMAScript高級程序設計書,原型鏈的基本思想就是利用原型讓一個引用類型繼承另外一個引用類型的屬性和方法。通俗的說原型鏈就是通過構造函數、原型與實例之間形成的一種鏈試關系,每個構造函數都有一個原型對象,原型對象都包含一個指向構造函數的指針,而實例都包含一個指向原型對象內部的指針。對於更多的原型和原型鏈知識我就不在這裏一一的說明了,大家可以通過查閱資料,進入更深的理解。
3.constructor 方法
使用constructor 方法判斷數組的原理是因為每個實例都有與之對應的構造函數,我們可以通過判斷它的構造函數,從而判斷它屬於哪個類型。但是該方法也存在不足,因為構造函數它能夠被重寫從而導致判斷不正確,不僅如此constructor方法與instanceof方法也存在相同的問題,即在不同框架(iframe)中創建的數組不會相互共享其prototype屬性。通過下面這個例子我們能夠很明顯的知道,該判斷是錯誤的。
var arr = ‘abc‘;
arr.constructor = Array;
arr.constructor === Array; //返回true
4.Array.isArray() 方法
Array.isArray() 函數的返回值為Boolean類型,如果指定的參數是數組,則返回true,否則返回false。
var arr = [];
var res = Array.isArray(arr);// true
var arr = new Array();
var res = Array.isArray(arr);// true
var arr = [1, 2, 3];
var res = Array.isArray(arr);// true
var res = Array.isArray("an array");
document.write(res);//false
說明:該方法是很好的判斷數組的方法,但是isArray() 在以下文檔模式中不受支持:Quirks、Internet Explorer 6 標準模式、Internet Explorer 7 標準模式、Internet Explorer 8 標準模式。所以在使用isArray()時要做版本判斷,該版本支持的時候就使用該方法,不支持的時候就使用object.prototype.to
String.call()方法,接下來將繼續介紹object.prototype.toString.call()方法的使用。
5.object.prototype.toString.call() 方法
該方法的原理是通過toString()方法轉換,直接輸出對象的類型(class)屬性。
1)判斷基本類型:
Object.prototype.toString.call(null);//”[object Null]”
Object.prototype.toString.call(undefined);//”[object Undefined]”
Object.prototype.toString.call(“abc”);//”[object String]”
Object.prototype.toString.call(123);//”[object Number]”
Object.prototype.toString.call(true);//”[object Boolean]”
2)判斷原生引用類型:
函數類型
Function fn(){console.log(“test”);}
Object.prototype.toString.call(fn);//”[object Function]”
日期類型
var date = new Date();
Object.prototype.toString.call(date);//”[object Date]”
數組類型
var arr = [1,2,3];
Object.prototype.toString.call(arr);//”[object Array]”
說明:這裏大家可能會比較好奇,為什麽不使用Object.toString呢?這是因為toString為Object的原型方法,而Array ,function等類型作為Object的實例,都重寫了toString方法。不同的對象類型調用toString方法時,根據原型鏈的知識,調用的是對應的重寫之後的toString方法(function類型返回內容為函數體的字符串,Array類型返回元素組成的字符串.....),而不會去調用Object上原型toString方法(返回對象的具體類型),所以采用Object.toString()不能得到其對象類型,只能將obj轉換為字符串類型;因此,在想要得到對象的具體類型時,應該調用Object上原型toString方法。
總結
通過上面的簡單講解,我相信大家也能夠清楚的知道,在數組判斷中,最好的判斷方法是Array.isArray() 方法和object.prototype.toString.call()方法,Array.isArray() 是最直接最簡單數組判斷方法,但是存在版本支持問題,所以在版本兼容的情況下我們就使用該方法。object.prototype.toString.call()方法也是很好的數組判斷方法,它解決了跨iframe 失效的問題,並且不存在版本支持問題,但是使用object.prototype.toString.call()是我們假設object.prototype.toString沒有被重寫的理想情況,因為它也有可能被重寫。所以通過一系列的判斷與對比,得出了判斷數組最好的辦法。
var arr1 = [8,4,9];
var arr2 = [{ a : 1, b : 2 }];
function isArray(value){
if (typeof Array.isArray === "function") {
return Array.isArray(value);
}else{
return Object.prototype.toString.call(value) === "[object Array]";
}
}
alert(isArray(arr1));// true
alert(isArray(arr2));// true
Javascript中數組的判斷方法