如何检查变量是否是javascript中的类型化数组?

AGD*_*AGD 15 javascript json typedarray stringify

我正在开发一款游戏,我们为数学类型广泛使用了类型数组(Float32Arrays).我们从JSON保存并加载游戏状态.JSON stringify输出的一个例子就是这样一个数组(在Chrome中)是:

"{"0":0,"1":0,"2":0,"length":3,"byteLength":12,"byteOffset":0,"buffer":{"byteLength":12}}"
Run Code Online (Sandbox Code Playgroud)

这会浪费空间并导致它们作为不方便的对象被加载.理想情况下,我们可以使用stringify'replacer'函数来测试变量是否是类型化数组,然后在这种情况下将其转换为bog标准数组.不幸的是,我不确定如何可靠地测试变量是否是类型化数组.

有帮助吗?

Gre*_*tum 23

ArrayBuffer.isView 应该帮助你.

var data = [0,1,2]
var dataBuffer = new ArrayBuffer( data )
var dataBufferView = new Float32Array( data )

ArrayBuffer.isView(data) //false
ArrayBuffer.isView(dataBuffer) //false
ArrayBuffer.isView(dataBufferView) //true
dataBuffer instanceof ArrayBuffer //true
Run Code Online (Sandbox Code Playgroud)

  • 所以,你可以使用`ArrayBuffer.isView(dataBufferView)&&!(dataBufferView instanceof DataView)`.整齐! (3认同)

T.J*_*der 15

如果你对它是一个Float32Array 一个子类感到满意Float32Array,请参阅Anton的回答instanceof.

如果您需要知道它是特定Float32Array而不是子类,您可以使用yourObject.constructor === Float32Array:

if (yourObject.constructor === Float32Array) {
     // It's a Float32Array
}
Run Code Online (Sandbox Code Playgroud)

实例:

if (typeof Float32Array === "undefined") {
  console.log("This browser doesn't support Float32Array");
} else {
  var array = new Float32Array(10);
  console.log(array.constructor === Float32Array); // true
}
Run Code Online (Sandbox Code Playgroud)

但请注意,如果对象来自不同的环境(如另一个框架),则会失败,因为不同的环境具有不同的Float32Array构造函数(即使它们执行相同的操作).

如果你需要支持constructor不起作用的情况,你可以使用这个Object.prototype.toString.call(yourObject)技巧.这将为所有JavaScript内置类型([object Array],[object Date]等)返回一个有用的字符串.每个规范,Object.prototype.toString当应用于类型化数组时,必须以格式返回字符串"[object TypedArrayNameHere]".

所以:

if (Object.prototype.toString.call(yourObject) === "[object Float32Array]") {
     // It's a Float32Array
}
Run Code Online (Sandbox Code Playgroud)

实例:

if (typeof Float32Array === "undefined") {
  console.log("This browser doesn't support Float32Array");
} else {
  console.log("Object.prototype.toString.call(new Float32Array()) returns: \"" +
    Object.prototype.toString.call(new Float32Array()) + "\"");
}
Run Code Online (Sandbox Code Playgroud)

请注意,可以创建与其类型相关的对象,使Object.prototype.toString返回与返回的相同(例如)Float32Array:

const real = new Float32Array();
const fake = {
  get [Symbol.toStringTag]() {
    return "Float32Array";
  }
};
const realString = Object.prototype.toString.call(real);
const fakeString = Object.prototype.toString.call(fake);
console.log(realString);
console.log(fakeString);
console.log(realString === realString);

// You can also create a class that returns objects that lie:
class Foo {
  get [Symbol.toStringTag]() {
    return "Float32Array";
  }
}
const fake2 = new Foo();
console.log(Object.prototype.toString.call(fake2));
Run Code Online (Sandbox Code Playgroud)


Ant*_*ton 13

你也可以使用yourObject instanceof Float32Array建筑.true如果您的对象是实例,则返回Float32Array,false在其他情况下.

if (yourObject instanceof Float32Array) {
    // your code here
}
Run Code Online (Sandbox Code Playgroud)


jcu*_*bic 8

我找到了一个更好的方法,如果你想测试每一个可能的 TypedArray,根据MDN,你可以得到TypedArray构造函数。使用此构造函数,您可以测试某些内容是否属于其类型:

var x = new Uint32Array();
var TypedArray = Object.getPrototypeOf(Uint8Array);
console.log(x instanceof TypedArray);
Run Code Online (Sandbox Code Playgroud)

您可以将其保存到如下函数中:

const isTypedArray = (function() {
  const TypedArray = Object.getPrototypeOf(Uint8Array);
  return (obj) => obj instanceof TypedArray;
})();
Run Code Online (Sandbox Code Playgroud)