2

私は完全に混乱しています。私はこれが何百万回も尋ねられたことを知っています。そして私は次のような質問を見てきました:

JavaScriptで何かが未定義でないかどうかをテストします

今問題は、チェックを行うときに、あなたができることが複数あることを発見したことです。

オブジェクトが配列であるかどうかを確認する必要があります。そのためには、「length」プロパティが存在するかどうかを確認します。今、私は何を使用しますか?

 if (obj.length)

また

 if (obj.length === undefined)

また

 if (typeof obj.length === "undefined")

また

if (obj.length == null)

または、他の何か?

===これは型変換を行わないことを理解しています。ifステートメントは「truthy」または「falsey」の値obj.lengthを必要としているだけです。つまり、長さが0の場合はfalseを返しますが、それは私たちが望んでいることではありません。それが定義されているかどうかを確認したいと思います。だから私はタイプテストに行きます。しかし、どちらの方法が最適ですか?

これが私が行ったいくつかのテストです。2、3、4が動作します。

ここに画像の説明を入力してください

間にあるものでごめんなさい。私はこのページのコンソールでそれを行っていました。

4

6 に答える 6

4

短い答え:

if (obj instanceof Array) {
    // obj is an array
}

objまたは、が定義されているかどうかわからない場合:

if ((typeof obj !== "undefined") && (obj instanceof Array)) {
    // obj is an array
}

なぜあなたが正しくないのかを議論するには:

obj.anyPropertyReferenceErrorifobjが未定義の場合にスローされます。これはあなたが置く4つのものすべてに影響します。

if (obj.length)空の配列の場合はfalseと評価されますが、これは必要なものではありません。長さは0(偽の値)であるため、誤って不正確になります。別のオブジェクトにプロパティがある場合にも、これには問題が発生する可能性がありlengthます。

if (obj.length === undefined)通常は機能しundefinedますが、再定義できるため、眉をひそめています。誰かがを書くことによってあなたのコードを壊す可能性がありますundefined = obj.length。これにより、フォールスネガティブが発生する可能性もあります。objたまたま「長さ」というプロパティがあり、それが誤って配列と呼ばれる可能性があります。

if (typeof obj.length === "undefined")正常に動作しますが、上記と同じフォールスネガティブを検出できます。

if (obj.length == null)正常に動作しますが、上記と同じバグがあります。double-equals(==)では、とに一致nullundefinedます。

于 2013-03-15T02:45:12.557 に答える
2

私は`をします

obj instanceof Array

objが配列かどうかを確認するには

http://jsfiddle.net/Tcjk4/

于 2013-03-15T02:42:35.483 に答える
2

価値があるのは、jQueryが何かが配列であるかどうかをチェックする方法です。

isArray: Array.isArray || function( obj ) {
    return jQuery.type(obj) === "array";
},

これは、利用可能な場合はES5を使用Array.isArrayするか、古いブラウザのカスタムチェックを使用します。jQueryは、この関数をとしてアクセス可能にし$.isArrayます。

jQuery.type基本的にはtypeof、JavaScript言語のいくつかの制限とブラウザのバグを回避する拡張機能です。オブジェクトのようなもの(、、偶数)をtypeof返すのに対し、オブジェクトの内部JavaScript [[Class]]プロパティを返します。'object'{}[]null$.type

実際、タイプを判別するこの方法は、実際には以下よりも安全ですinstanceof

どちらも非常に無害instanceofconstructor見え、オブジェクトが配列であるかどうかを確認するための優れた方法のようです。

マルチフレームDOM環境でのスクリプト作成に関しては、問題が発生します。一言で言えば、Arrayあるiframe内で作成されたオブジェクトは、別のiframe内で作成された配列と[[Prototype]]を共有しません。それらのコンストラクターは異なるオブジェクトであるため、両方 instanceofconstructorチェックが失敗します。

var iframe = document.createElement('iframe');
document.body.appendChild(iframe);
xArray = window.frames[window.frames.length-1].Array;
var arr = new xArray(1,2,3); // [1,2,3]  

// Boom!
arr instanceof Array; // false  

// Boom!
arr.constructor === Array; // false
于 2013-03-15T02:58:06.760 に答える
1

答えよりもコメントが多い。

のようなテストobject instanceof Arrayはほとんどの場合機能しますが(フレームまたはウィンドウ間通信が関係する場合は失敗する可能性があります)、実際に何をテストする必要があるかを検討し、それに応じてテストを設計することをお勧めします。オブジェクトが配列であるかどうかを明示的にテストする必要はほとんどありません。

この場合、オブジェクトの数値プロパティを反復処理するために長さプロパティを使用したいようです。

その場合は、lengthプロパティの値を読み取って使用するだけです。undefinedプロパティが欠落しているか、値が割り当てられていないか、またはの値があるかどうかにかかわらず0、ループを実行する必要はありません。幸い、これらすべてのテストを一度に実行できます(また、値がNullまたはの場合は処理をスキップ''できます。これも理にかなっているようです)。

if (obj.length) {
  // iterate over numeric properties of obj
}

これにより、メソッドがジェネリックになり、適切な長さプロパティといくつかの数値プロパティを持つ任意のオブジェクト(jQueryオブジェクトやHTMLCollectionオブジェクトなど)に適用できます。

配列の他の機能(プッシュやスライスなど)が必要な場合は、それらをテストすることもできます。

テストをロジックフォークとして使用している場合(たとえば、配列の場合は1つのことを行い、プレーンオブジェクトの場合は別のことを行います)、それが賢明なことであるかどうかを検討する必要があります。

于 2013-03-15T04:32:57.433 に答える
0
var sizeArrayOrObject = function(obj) {
    var size = 0, key;
    for (key in obj) {
        if (typeof obj.key === 'undefined') size++;
    }
    return size;
};

sizeArrayOrObject([]);  // 0
sizeArrayOrObject([5,6]);  // 2

sizeArrayOrObject({});  // 0
sizeArrayOrObject({id:8});  // 1
于 2013-03-15T02:55:13.903 に答える
0

underscore.jsを使用するにはhttp://underscorejs.org/#isObject

_.isArray(object) オブジェクトが配列の場合はtrueを返します。

(function(){ return _.isArray(arguments); })();
=> false
_.isArray([1,2,3]);
=> true

_.isObject(value) valueがオブジェクトの場合はtrueを返します。JavaScriptの配列と関数はオブジェクトですが、(通常の)文字列と数値はオブジェクトではないことに注意してください。

_.isObject({});
=> true
_.isObject(1);
=> false
于 2013-03-15T03:05:48.020 に答える