2

我完全糊涂了。我知道这已经被问了一百万次了。我看过以下问题:

测试 JavaScript 中是否未定义某些内容

现在的问题是,在进行检查时,我发现您可以做很多事情。

我需要检查一个对象是否是一个数组,为此我检查“长度”属性是否存在。现在我会用什么?

 if (obj.length)

或者

 if (obj.length === undefined)

或者

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

或者

if (obj.length == null)

或者是其他东西?

我知道这===不会进行任何类型转换,并且 if 语句只是想要一个“真实”或“虚假”值,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.anyProperty将抛出一个ReferenceErrorifobj未定义。这会影响您放置的所有四样东西。

if (obj.length)将为空数组评估为 false,这不是您想要的。因为长度为 0(一个虚假值),所以它会错误地不准确。如果另一个对象具有length属性,这也可能会出现问题。

if (obj.length === undefined)通常会起作用,但由于undefined可以重新定义,因此不受欢迎。有人可能会通过编写undefined = obj.length. 这也可能产生假阴性;obj可能碰巧有一个名为“length”的属性,它会错误地将其称为数组。

if (typeof obj.length === "undefined")工作正常,但可以检测到与上述相同的假阴性。

if (obj.length == null)可以正常工作,但有与上述相同的错误。在双等号 ( ==) 中,它匹配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返回'object'任何类似对象({}, [], even null),$.type返回对象的内部 JavaScript [[Class]]属性。

事实上,这种确定类型的方法实际上比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 属性来迭代对象的数字属性。

如果是这种情况,您需要做的就是读取长度属性的值并使用它。无论该属性是否丢失,或尚未分配值,或值为undefinedor 0,您都不想执行循环。幸运的是,您可以一次性完成所有这些测试(如果值为Nullor '',也可以跳过处理,这似乎也很明智):

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

这将使该方法具有通用性,因此它可以应用于任何具有合适长度属性和一些数字属性的对象(例如,jQuery 对象或 HTMLCollection 对象)。

如果您需要数组的某些其他功能(例如 push 或 slice),您也可以测试这些功能。

如果您将测试用作逻辑分支(例如,如果它是一个数组做一件事,如果它是一个普通对象做另一件事),那么您应该考虑这样做是否明智。

于 2013-03-15T04:32:57.433 回答
0

使用 underscore.js http://underscorejs.org/#isObject

_.isArray(object) 如果 object 是一个数组,则返回 true。

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

_.isObject(value) 如果 value 是 Object,则返回 true。请注意,JavaScript 数组和函数是对象,而(普通)字符串和数字不是。

_.isObject({});
=> true
_.isObject(1);
=> false
于 2013-03-15T03:05:48.020 回答
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 回答