我完全糊涂了。我知道这已被问了一百万次。我看过像这样的问题:
Test if something is not undefined in JavaScript
现在的问题是,在进行检查时,我发现了一些你可以做的事情。
我需要检查一个对象是否是一个数组,为此我检查是否存在“length”属性。现在我会用什么?
if (obj.length)
或
if (obj.length === undefined)
或
if (typeof obj.length === "undefined")
或
if (obj.length == null)
或其他什么?
我理解===
没有进行任何类型转换,而if语句只是想要一个“truthy”或“falsey”值,这意味着如果长度为0,obj.length
将返回false ,但那不是我们想要的。我们现在想要定义它。这就是我去打字测试的原因。但哪种方式最好?
以下是我做过的一些测试。 2,3和4工作。
对不起介于两者之间的东西。我是在这个页面的控制台中做的。
答案 0 :(得分:4)
简短回答:
if (obj instanceof Array) {
// obj is an array
}
或者,如果您不知道是否定义了obj
:
if ((typeof obj !== "undefined") && (obj instanceof Array)) {
// obj is an array
}
讨论你的不正确的原因:
如果obj.anyProperty
未定义, ReferenceError
将抛出obj
。这会影响你提出的所有四件事。
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)
可以正常工作,但有与上面相同的错误。在双等号(==
)中,它与null
和undefined
匹配。
答案 1 :(得分:2)
答案 2 :(得分:2)
对于它的价值,这里是jQuery checks whether something is an array:
的方式isArray: Array.isArray || function( obj ) {
return jQuery.type(obj) === "array";
},
如果可用,则使用ES5的Array.isArray
,或者在旧浏览器中使用自定义检查。 jQuery使这个函数可以$.isArray
访问。
jQuery.type
是basically增强版typeof
,可以解决JavaScript语言和浏览器错误的一些限制。 typeof
为任何类似对象('object'
,{}
,甚至[]
)返回null
,$.type
返回内部JavaScript {{3}对象的属性。
实际上,这种确定类型[[Class]]的方法:
instanceof
和constructor
看起来都很无辜,看起来很棒 检查对象是否为数组的方法。在多帧DOM中编写脚本时会出现问题 环境。简而言之,在一个iframe中创建了
Array
个对象 不要与在另一个内创建的数组共享[[Prototype]] iframe中。他们的构造函数是不同的对象,所以两者instanceof
和constructor
检查失败: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
答案 3 :(得分:1)
更多评论而非回答。
虽然类似object instanceof Array
的测试在大多数情况下都会起作用(在涉及帧或窗口间通信的情况下可能会失败),但最好还是考虑一下你真正需要测试的内容并相应地设计测试。显式测试对象是否是数组几乎总是不必要的。
在这种情况下,您似乎只想使用length属性迭代对象的数字属性。
如果是这种情况,您需要做的就是读取length属性的值并使用它。无论属性是缺失,还是尚未分配值,或者值为undefined
或0
,您都不希望执行循环。幸运的是,您可以一次性完成所有这些测试(如果值为Null
或''
,也可以跳过处理,这似乎也是合理的):
if (obj.length) {
// iterate over numeric properties of obj
}
这将使该方法通用,因此它可以应用于具有合适长度属性和一些数字属性的任何Object(例如jQuery对象或HTMLCollection对象)。
如果您需要阵列的其他功能(例如推或切片),您也可以测试它们。
如果你使用测试作为逻辑分支(例如,如果它是一个数组做一件事,如果它是一个普通对象做其他事情)那么你应该考虑这是否是一个明智的事情。
答案 4 :(得分: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
答案 5 :(得分:0)
使用underscore.js http://underscorejs.org/#isObject
<强> _。IsArray的(对象)强> 如果object是一个数组,则返回true。
(function(){ return _.isArray(arguments); })();
=> false
_.isArray([1,2,3]);
=> true
<强> _。则IsObject(值)强> 如果value是Object,则返回true。请注意,JavaScript数组和函数是对象,而(普通)字符串和数字则不是。
_.isObject({});
=> true
_.isObject(1);
=> false