如何检查变量是否是javascript中的类型化数组
How to check if a variable is a typed array in javascript?
我正在制作一款游戏,我们在数学类型中大量使用类型化数组(Float32Arrays)。我们从JSON中保存和加载游戏。JSON stringify输出的一个例子是这样一个数组(在Chrome中)是:
"{"0":0,"1":0,"2":0,"length":3,"byteLength":12,"byteOffset":0,"buffer":{"byteLength":12}}"
这会浪费空间,并导致它们被加载为不方便的对象。理想情况下,我们可以使用stringify 'replacer'函数来测试变量是否为类型数组,然后在这种情况下将其转换为标准数组。不幸的是,我不确定如何可靠地测试变量是否是类型化数组。
帮忙吗?
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
如果你对它是Float32Array
或 Float32Array
的子类感到满意,它们将来自相同的领域(松散,窗口)作为你正在检查的代码,请参阅Anton使用instanceof
的回答。
如果你需要知道它是特别是一个Float32Array
而不是一个子类(并且它来自同一个领域),你可以使用yourObject.constructor === Float32Array
:
if (yourObject.constructor === Float32Array) {
// It's a Float32Array
}
生活的例子:
if (typeof Float32Array === "undefined") {
console.log("This browser doesn't support Float32Array");
} else {
var array = new Float32Array(10);
console.log(array.constructor === Float32Array); // true
}
但是请注意,如果对象起源于不同的领域(如另一个框架),则会失败,因为不同的环境有不同的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
}
生活的例子:
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()) + "'"");
}
请注意,可以创建与其类型有关的对象,使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));
您也可以使用yourObject instanceof Float32Array
结构。如果对象是Float32Array
的实例,则返回true
,否则返回false
。
if (yourObject instanceof Float32Array) {
// your code here
}
我找到了一个更好的方法,如果你想测试每一个可能的TypedArray,根据MDN,你可以得到TypedArray构造函数。使用这个构造函数,您可以测试某些内容是否属于其类型:
var x = new Uint32Array();
var TypedArray = Object.getPrototypeOf(Uint8Array);
console.log(x instanceof TypedArray);
你可以像这样保存到一个函数中:
const isTypedArray = (function() {
const TypedArray = Object.getPrototypeOf(Uint8Array);
return (obj) => obj instanceof TypedArray;
})();
如果您想要捕获任何ArrayBufferView和DataView类型的更一般的测试,您可以使用:
if (Object.prototype.toString.call(yourObject.buffer) === "[object ArrayBuffer]") {
// It's either an ArrayBufferView or a DataView
}
我很惊讶没有人得到下面这张。这应该在大多数情况下工作,以确定您是否有一个类型化数组:
function isTypedArray(a) { return !!(a?.buffer instanceof ArrayBuffer && a?.BYTES_PER_ELEMENT); }
var a = [];
console.log(isTypedArray(a)); // (false);
var a = new Float32Array(3);
console.log(isTypedArray(a)); // (true);
var dataView = new DataView(a.buffer);
console.log(isTypedArray(dataView)); // (false);
console.log(isTypedArray(Float32Array)); // (false);
当然,这是"鸭子类型",a instanceof Float32Array
或类似的是确定特定类型的最佳方法。
所有类型数组都继承自ArrayBuffer。该类型包含一个byteLength属性,所以请检查该属性是否可用。
function isTypedArray(obj)
{
return !!obj && obj.byteLength !== undefined;
}
查找所有返回 TypedArray的构造函数的简单方法:
isTypedArray = _ => _?.prototype?.__proto__?.constructor?.name == "TypedArray";
for (const key of Object.getOwnPropertyNames(window)) {
const obj = window[key];
if (isTypedArray(obj)) {
console.log(key, "is a TypedArray");
}
}
当前Chrome的输出:
Uint8Array is a TypedArray
Int8Array is a TypedArray
Uint16Array is a TypedArray
Int16Array is a TypedArray
Uint32Array is a TypedArray
Int32Array is a TypedArray
Float32Array is a TypedArray
Float64Array is a TypedArray
Uint8ClampedArray is a TypedArray
BigUint64Array is a TypedArray
BigInt64Array is a TypedArray
- 为什么不't Javascript对我的输入值进行了一些重新检查
- 创建一个类似链接的按钮,并通过Javascript函数打开一个新的弹出窗口
- 将函数的上下文应用于javascript变量
- 使用php或javascript从facebook相册URL中删除多余的部分
- 正在添加'X'按钮,在文本字段旁边使用javascript
- 如何在JavaScript中将字符串转换为函数引用
- Javascript-将类型化数组保存为blob,并作为二进制数据读回
- 了解 JavaScript 中类型化数组的概念
- 如何检查是否支持 javascript 类型化数组
- 用于在javascript中存储对象的类型化数组
- 如何在javascript中使用类型化变量
- 在Javascript中将字符串转换为类型化数组
- 如何在JavaScript类型化数组中使用字符串
- 是否有可能在JavaScript中使用类型化数组从4x Uint8转换为Uint32 ?
- 如何检查变量是否是javascript中的类型化数组
- 是否可以将Javascript匿名对象强制转换为类型化对象?怎样
- 使用类型化的javascript/jquery库使光标具有相同的文本大小
- 带有类型化 JavaScript 库的光标跳到新行,并且不会“键入”工作
- 如何在 Safari 中声明类型化数组?(JavaScript)
- JavaScript: Web Worker和类型化数组