检测对象是否为Array或类型化数组

Detect if object is either an Array or typed array

本文关键字:类型化 数组 Array 对象 是否 检测      更新时间:2023-09-26

我需要确定给定的对象是Array还是类型化数组,如Float32Array

目前我正在检查是否定义了.length属性,但这并不总是指示数组。.forEach()或其他方法的存在性检查也会出现类似的问题。

几个instanceof检查就足够了,就像这里做的那样-但我想知道是否有一个简单的内置功能,例如,一个通用的Array.isArray()函数,做我需要的。

function isArrayOrTypedArray(x) {
    return Boolean(x && (typeof x === 'object') && (Array.isArray(x) || (ArrayBuffer.isView(x) && !(x instanceof DataView)));
}

遗憾的是,我不相信有。

您可以执行您提到的instanceof检查,或者您可以检查Object.prototype.toString.call(variable)的结果,看看它是否是预定义字符串("[object Array]", "[object Uint8Array]"等)之一。

(编辑:啊,我看到通过遵循您问题中的链接,代码也证明了这一点。)

虽然我认为,正如T.J. Crowder已经说过的,没有内置的功能,但您应该能够组合Array.isArrayArrayBuffer.isView来获得您想要的功能:

function isArrayOrTypedArray(x) {
  return Array.isArray(x) || (ArrayBuffer.isView(x) &&
      Object.prototype.toString.call(x) !== "[object DataView]");
}
如果x是一个数组,

Array.isArray(x)返回true。如果x是类型数组或DataView,则ArrayBuffer.isView(x)返回true,因此我们只需忽略x是DataView的情况即可获得我们想要的函数。

示范:

function isArrayOrTypedArray(x) {
  return Array.isArray(x) || (ArrayBuffer.isView(x) && Object.prototype.toString.call(x) !== "[object DataView]");
}
console.log(isArrayOrTypedArray());                    // false              
console.log(isArrayOrTypedArray({}));                  // false
console.log(isArrayOrTypedArray(null));                // false
console.log(isArrayOrTypedArray(undefined));           // false
console.log(isArrayOrTypedArray(new ArrayBuffer(10))); // false
console.log(isArrayOrTypedArray([]));                  // true
console.log(isArrayOrTypedArray([1,2,3,4,5]));         // true
console.log(isArrayOrTypedArray(new Uint8Array()));    // true
console.log(isArrayOrTypedArray(new Float32Array()));  // true
console.log(isArrayOrTypedArray(new Int8Array(10).subarray(0, 3))); // true
var buffer = new ArrayBuffer(2);
var dv = new DataView(buffer);
console.log(isArrayOrTypedArray(dv)); // false

你可以这样做:

function isArray(array) {
    if((array.length || array.length === 0) && (array.constructor !== String)) {
        return true;
    }
    return false;
}

注意,String也有一个长度属性,我们需要排除它,因此constructor检查

判断x是否为ArrayBuffer,您可以利用new DataView(x)抛出TypeError的事实:DataView构造函数的第一个参数必须是arraybuffer;如果x不是ArrayBuffer.

换句话说,只要做:

function isArrayBuffer(x) {
    try {
        new DataView(x);
        return true;
    }
    catch (TypeError) {
        return false;
    }
}

要测试一个东西是否是typearray,我相信ArrayBuffer.isView可以胜任。

您可以使用obj.constructor.name作为获取对象名称的方式,而不是使用instanceof匹配阶梯。所有这些数组的共同之处在于它们的类名中都有Array,并且array.length属性是一个数字。

function isArray(x) {
  if (typeof x.length === 'number' 
    && x.constructor.name.includes('Array')) {
    return true;
  }
  return false;
}

无论如何,这在Javascript/Node的后续版本中都有效。如果你的JS版本支持,你可以使用name.includes

Array.constructor.name对于[]Array,对于类型化数组则是Uint8Array

在其他版本的JavaScript中,您可能需要obj.prototype.constructor.name .