javascript 如何检查变量是否是javascript中的类型化数组?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15251879/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to check if a variable is a typed array in javascript?
提问by AGD
I'm working on a game and we make extensive use of typed arrays (Float32Arrays) for our math types. We save and load the gamestate from JSON. An example of JSON stringify output is for such an array (in Chrome) is:
我正在开发一个游戏,我们广泛使用类型化数组 (Float32Arrays) 作为我们的数学类型。我们从 JSON 保存和加载游戏状态。JSON stringify 输出的一个例子是这样一个数组(在 Chrome 中)是:
"{"0":0,"1":0,"2":0,"length":3,"byteLength":12,"byteOffset":0,"buffer":{"byteLength":12}}"
This wastes space and causes them to be loaded as objects which is inconvenient. Ideally we could use the stringify 'replacer' function to test if a variable is a typed array, and then convert it to a bog standard array in that case. Unfortunately I'm not sure how to reliably test whether a variable is a typed array or not.
这会浪费空间并导致它们作为对象加载,这很不方便。理想情况下,我们可以使用 stringify 'replacer' 函数来测试变量是否是类型化数组,然后在这种情况下将其转换为 bog 标准数组。不幸的是,我不确定如何可靠地测试变量是否是类型化数组。
Any help?
有什么帮助吗?
采纳答案by T.J. Crowder
If you're happy with it being a Float32Array
ora subclass of Float32Array
and they'll be from the same realm(loosely, window) as the code you're checking, see Anton's answer using instanceof
.
如果你用它是一个快乐Float32Array
或子类Float32Array
,他们会是同一领域(松散,窗)的代码,你要检查,看安东的回答使用instanceof
。
If you need to know that it's specificallya Float32Array
and not a subclass (and its from the same realm), you could use yourObject.constructor === Float32Array
:
如果您需要知道它具体是一个Float32Array
而不是一个子类(并且来自同一领域),您可以使用yourObject.constructor === Float32Array
:
if (yourObject.constructor === Float32Array) {
// It's a Float32Array
}
Live example:
现场示例:
if (typeof Float32Array === "undefined") {
console.log("This browser doesn't support Float32Array");
} else {
var array = new Float32Array(10);
console.log(array.constructor === Float32Array); // true
}
But note that will fail if the object originates in a different realm (like another frame), because different environments have different Float32Array
constructors (even though they do the same thing).
但请注意,如果对象来自不同的领域(如另一个框架),这将失败,因为不同的环境具有不同的Float32Array
构造函数(即使它们做相同的事情)。
If you need to support cases where constructor
won't work, you can use the Object.prototype.toString.call(yourObject)
trick. That returns a useful string for all of the JavaScript built-in types ([object Array]
, [object Date]
, etc.) Per specification, Object.prototype.toString
when applied to a typed array must return the string in the format "[object TypedArrayNameHere]"
.
如果您需要支持constructor
不起作用的情况,您可以使用该Object.prototype.toString.call(yourObject)
技巧。这为所有 JavaScript 内置类型([object Array]
、[object Date]
等)返回一个有用的字符串。根据规范,Object.prototype.toString
当应用于类型化数组时,必须返回格式为 的字符串"[object TypedArrayNameHere]"
。
So:
所以:
if (Object.prototype.toString.call(yourObject) === "[object Float32Array]") {
// It's a Float32Array
}
Live example:
现场示例:
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()) + "\"");
}
Note that it's possible to create objects that lie about their type, making Object.prototype.toString
return the same thing it would return for (say) 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));
回答by Greg Tatum
ArrayBuffer.isView
should help you out.
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
回答by Anton
You also can use yourObject instanceof Float32Array
construction.
It returns true
if your object is an instance of Float32Array
and false
in other case.
您也可以使用yourObject instanceof Float32Array
构造函数。true
如果您的对象是Float32Array
和false
在其他情况下的实例,它会返回。
if (yourObject instanceof Float32Array) {
// your code here
}
回答by James Wilkins
I'm surprised no one got this one below. This should work in most cases to figure out if you have a typed array:
我很惊讶没有人在下面找到这个。在大多数情况下,这应该可以确定您是否有类型化数组:
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);
Of course this is "duck typing", and a instanceof Float32Array
or similar is the best way to know for sure for specific types.
当然,这是“鸭子类型”,a instanceof Float32Array
或者类似的方法是确定特定类型的最佳方式。
回答by visibleman
If you'd like a more general test that catches any of the ArrayBufferView and DataView types you can use:
如果您想要一个更通用的测试来捕获任何 ArrayBufferView 和 DataView 类型,您可以使用:
if (Object.prototype.toString.call(yourObject.buffer) === "[object ArrayBuffer]") {
// It's either an ArrayBufferView or a DataView
}
回答by Martin Wantke
All typed arrays are inherit from ArrayBuffer. This type contains a byteLength property, so simple check if this property is available.
所有类型化数组都继承自 ArrayBuffer。此类型包含一个 byteLength 属性,因此只需检查此属性是否可用。
function isTypedArray(obj)
{
return !!obj && obj.byteLength !== undefined;
}