我正在寻找一种测试JavaScript对象是否为某种有序对象的有效方法。希望有人知道不涉及编写一些大型类型评估函数的技巧。幸运的是,我不必处理IE
根本的问题是:我需要弄清楚是否要在对象上运行for循环或for ... in循环。但是,我并不总是知道对象是否将是对象文字,数组,jQuery对象等。
这是我遇到的一些障碍:
我显然不能只使用typeof
,因为数组和对象都返回object
。
我显然不能只使用Object.prototype.toString.call(collection)
,因为虽然数组确实返回了[object Array]
,但是自定义排序的集合(如jQuery对象)仍然返回了[object Object]
,我想要进行此测试的全部原因是确定我是否需要for循环或一个for ... in循环。在jQuery对象上使用for ... in循环包含的属性实际上不是集合的一部分,并且使事情变得混乱。
我确实提出了一个看起来像这样的想法:
function isOrdered(item) {
// Begin by storing a possible length property
// and defaulting to false for whether the item
// is ordered.
var len = item.length, isOrdered = false;
// Functions are an easy test.
if (typeof item === 'function') {
return false;
}
// The Arguments object is the only object I know of
// with a native length property that can be deleted
// so we account for that specifically too.
if (Object.prototype.toString.call(item) === '[object Arguments]') {
return true;
}
// Attempt to delete the item's length property.
// If the item is ordered by nature, we won't get
// an error but we also won't be able to delete
// this property.
delete item.length;
// So if the length property still exists as a
// number, the item must be an ordered collection.
if (typeof item.length === 'number') {
isOrdered = true;
}
// If we originally stored a custom length property,
// put it back.
if (len !== undefined) {
item.length = len;
}
// Return the result.
return isOrdered;
}
到目前为止,该技术已经通过了所有测试,但是我担心删除自定义对象上的属性可能会导致性能下降,而且我不确定100%不会丢失某些东西。有谁有更好的主意吗?
最佳答案
您可以执行以下操作:
function isOrdered(item) {
var len = item.constructor.prototype.length;
return len === +len;
}
如果'item'是一个js对象,它将评估为false,但是如果它是数组或jQuery集合,则将返回true。
请注意,数组以外的其他东西都可以具有数字长度属性(尝试检查函数的长度)。如果您可能传递整数或函数之类的信息,则您将需要做一些更复杂的事情,但这应该可以解决您在发布的代码中遇到的所有情况。另外,我认为删除length属性可能会导致无法预料的结果,因此,我会避免使用这种方法来支持不会使您正在测试的对象发生突变的方法。
关于javascript - 如何测试JavaScript对象是否为对象的有序类型,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20896296/