Monday, May 20, 2024
 Popular · Latest · Hot · Upcoming
54
rated 0 times [  55] [ 1]  / answers: 1 / hits: 26871  / 11 Years ago, wed, march 6, 2013, 12:00:00

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:



{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.



Any help?


More From » json

 Answers
17

If you're happy with it being a Float32Array or a 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.



If you need to know that it's specifically a Float32Array and not a subclass (and its from the same realm), you could use 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).



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].



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:





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));




[#79786] Tuesday, March 5, 2013, 11 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
deiong

Total Points: 15
Total Questions: 103
Total Answers: 99

Location: Sudan
Member since Thu, May 7, 2020
4 Years ago
;