Javascriptでは配列の正しい姿勢を判断します.
4537 ワード
Javascriptでは、変数が配列かどうかをどう判断しますか?
最高の方法はES 5で提供される
index.httmコード:
これは各frameには自分の実行環境があり、frameにまたがって実装されたオブジェクトは互いにプロトタイプチェーンを共有しないからです.a instance of window.frames[0].Arayを印刷すれば、結果はtrueです.
特性チェック
例えばjQueryで配列判定を行う関連コード(PS:jQuery 1.10.1より抜粋して、最近のバージョンのjQueryはAray.isAray()だけを残しています.ES 5に対応していないブラウザに対しては互換性がありません.
ECMA-226: Javascript配列タイプ検出:より強力なisAray関数 を作成する. JavaScript:Object.prototype.toString方法の原理
最高の方法はES 5で提供される
Array.isArray()
方法です.var a = [0, 1, 2];
console.log(Array.isArray(a)); // true
しかし、低バージョンIEはES 5をサポートしていないため、互換性が必要なら、他の方法を考える必要があります.typeof
配列は特殊なオブジェクトであることを知っています.だから、配列のtypeofもobjectです.nullの結果もobjectなので、typeof演算子を使って配列を判断する必要があります.var a = [0, 1, 2];
// object null、
console.log(typeof a === 'object' && a !== null && Object.prototype.toString.call(a) !== '[object Object]'); // true
instanceof
instance of演算子の使い方を思い出します.a instance of bは、trueに戻ると、aがbの一例であることを表す.もしa instance of Arayがtrueに戻ると、aが配列タイプということですか?instance ofと同門のconstructorがありますが、同じように判断できますか?var a = [0, 1, 2];
console.log(a instanceof Array); // true ?
console.log(a.constructor === Array); // true ?
答えは否定です.入れ子frameの場合に注意が必要です.index.httmコード:
<iframe src='a.htm'></iframe>
<script>
window.onload = function() {
var a = window.frames[0].a;
console.log(a instanceof Array); // false
console.log(a.constructor === Array); // false
};
</script>
a.httmコード:<script>
window.a = [1, 2, 3];
</script>
index.httmコードでは変数aは確かに配列されていますが、a instance of Arayの結果はfalseです.これは各frameには自分の実行環境があり、frameにまたがって実装されたオブジェクトは互いにプロトタイプチェーンを共有しないからです.a instance of window.frames[0].Arayを印刷すれば、結果はtrueです.
特性チェック
var a = [0, 1, 2];
if (a.sort) {
//
}
当てにならないです.もしある対象にソトに値するキーがありますか?var a = {sort: 'me'};
if (a.sort) {
// ?
//
}
正しい姿勢はObject.prototype.toString()を使って判断します.var a = [0, 1, 2];
console.log(Object.prototype.toString.call(a) === '[object Array]'); // true
実際には、これもいくつかのクラスの配列(または他のタイプ)によって判断される主流の方法である.例えばjQueryで配列判定を行う関連コード(PS:jQuery 1.10.1より抜粋して、最近のバージョンのjQueryはAray.isAray()だけを残しています.ES 5に対応していないブラウザに対しては互換性がありません.
isArray: Array.isArray || function( obj ) {
return jQuery.type(obj) === "array";
},
type: function( obj ) {
if ( obj == null ) {
return String( obj );
}
return typeof obj === "object" || typeof obj === "function" ?
class2type[ core_toString.call(obj) ] || "object" :
typeof obj;
},
jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {
class2type[ "[object " + name + "]" ] = name.toLowerCase();
});
コードがはっきりしていて、原生をサポートするAray.isAray()のように直接判断し、サポートしない場合はtoString()を呼び出して判断します.他の多くのタイプの変数の判断もToStering()法によるものと見られます.もちろんここで言っているtoString()はすべてObjectのプロトタイプチェーン上のtoString()の方法です.console.log(Object.prototype.toString.call(10)); // [object Number]
console.log(Object.prototype.toString.call('hello')); // [object String]
console.log(Object.prototype.toString.call(true)); // [object Boolean]
console.log(Object.prototype.toString.call([])); // [object Array]
console.log(Object.prototype.toString.call({})); // [object Object]
console.log(Object.prototype.toString.call(function(){})); // [object Function]
console.log(Object.prototype.toString.call(/a/g)); // [object RegExp]
console.log(Object.prototype.toString.call(null)); // [object Null]
console.log(Object.prototype.toString.call(undefined)); // [object Undefined]
console.log(Object.prototype.toString.call(new Date())); // [object Date]
Object.prototype.toString()はなぜこのようなタイプの文字列を返しますか?ECMA-226:
Object.prototype.toString( ) When the toString method is called, the following steps are taken:
1. Get the [[Class]] property of this object.
2. Compute a string value by concatenating the three strings “[object “, Result (1), and “]”.
3. Return Result (2)
上記の仕様では、Object.prototype.toStringの挙動を定義しています.まず、対象の内部属性[Class]を取得し、この属性に基づいて、「[object Aray]」と似た文字列を結果として返します.この方法を利用して、またコールに協力して、私達はいかなる対象の内部の属性[クラス]を得ることができて、そしてタイプの検査を文字列の比較に転化して、私達の目的を達成します.まずはECMA標準でのアラyの説明を見てみましょう.new Array([ item0[, item1 [,…]]])
The [[Class]] property of the newly constructed object is set to “Array”.
したがって、Javascriptでは、配列を判断する関数はこう書くことができます.function isArray(a) {
Array.isArray ? Array.isArray(a) : Object.prototype.toString.call(a) === '[object Array]';
}
リードMore: