1,真正的陣列的判斷方法
javascript中最簡單的宣告陣列方法為:
var a = [];
判斷是否為陣列的最直接的方法為:
a instanceof Array //true
a .constructor == . //true
這裡涉及到一個instanceof語法,instanceof是一個雲算符,與" -*/"一樣,它的語法如下:
result = obj intanceof class
是用來判斷一個物件是否是某個class的實例,運算結果回傳true或false。 javascript中class的定義又是透過建構函式進行初始化的,所以instanceof語法的右邊操作符class一定是Function的實例,也就是class instanceof Function一定是true,而且如果使用instanceof時右邊運算子不是Function,就會拋出TypeError異常。所有物件都是Object的實例,所以任何物件instanceof Object都會回傳true。雖然我們說物件都是透過建構函式進行初始化的,但是instanceof卻不是透過檢查物件是否由該函式構造的,而是透過是否由建構函式的prototype繼承來的,下面這個例子可以說明這個問題:
function Range(low, high) {
this. = low;
this.high = high;
}
Range.prototype.constructor == Range; //true
Range.prototype = {
include: function(x){ return (x >= this.low && x exclude: function(x){ return (x this.high); }
}
var r = new Range(0, 100);
r instanceof Range; //false
r instanceof Object; //true
Range.prototype.constructor == Objecct; //true
Range.prototype.constructor == Objecct; //true
這裡雖然r是透過new Range建構的,但是r卻並不是Range的實例,這就是問題所在,Range.prototype賦值語句覆蓋了預設的建構函數,沒對prototype賦值之前Range.prototype .constructor為Range,賦值之後變成了Object,這也好理解,因為
程式碼如下:
Range.prototype = {
include: function(x){ return (x >= this.low && x exclude: function(x){ return (x this.high); }
}
其實等價於:
程式碼如下:
Range.prototype = new Object({
include: function(x){ return (x >= this.low && x exclude: function(x){ return (x this.high); }
});
所以Range.prototype.constructor == Object,那麼透過new Range創建出來的實例當然就是Object的一個實例了。
看官方解釋更直接些:
The instanceof operator does not actually check whether r was initialized by the Range constructor. It checks whether it inherits from Range.prototype.
java與instanceof類似的功能,但是它返回的是具體的基本資料類型:number,string,function,object,undefined,boolean,只有這六種,不在這六種範圍內的都返回object,也就是說typeof( [])回傳的是object,而不是array。
另一個涉及的語法是constructor,constructor回傳物件的建構子:
程式碼如下:
var a = [];
a.constructor; //Array
コンストラクターはオブジェクトの初期化関数です。オブジェクトが配列の場合、そのコンストラクターはプロトタイプ内のコンストラクターであるため、必ずしも Array である必要はありません。変更される場合があります。
2. 疑似配列の判断方法
JavaScript には疑似配列があり、Array と同様のトラバースメソッドを使用してトラバースできます。長さを取得するための length 属性があります。 [] 添字を使用して、指定された要素を取得できます。この種のオブジェクトは、以下に示すように、疑似配列と呼ばれます。疑似配列かどうかの判定は、length 属性の有無と基本的な配列操作関数 splice の有無を判定するもので、判定方法は以下のとおりです。
戻り値 &&
typeof value === 'object ' &&
値のタイプ.length === '数値' &&
値のタイプ.splice === '関数' &&
!(value.propertyIsEnumerable('length'));
ここで、propertyIsEnumerable は、length 属性が利用可能かどうかを決定するために使用されます。実際、列挙するには、ネイティブ String オブジェクトも Array と同様の効果を持ちますが、これを Array オブジェクトとして扱うことはできません。 typeof は String オブジェクトであり文字列を返すため、ここでは typeof value == "object" と判断する必要があります。