Как проверить, является ли переменная типизированным массивом в javascript?

Я работаю над игрой, и мы широко используем типизированные массивы (Float32Arrays) для наших математических типов. Мы сохраняем и загружаем игру от JSON. Примером вывода строки JSON для такого массива (в Chrome) является:

"{"0":0,"1":0,"2":0,"length":3,"byteLength":12,"byteOffset":0,"buffer":{"byteLength":12}}"

Это освобождает пространство и заставляет их загружаться как объекты, которые неудобны. В идеале мы могли бы использовать функцию substitute 'replacer', чтобы проверить, является ли переменная типизированным массивом, а затем преобразует ее в стандартный массив bog. К сожалению, я не уверен, как надежно проверить, является ли переменная типизированным массивом или нет.

Любая помощь?

Ответ 1

Если вы довольны тем, что он является Float32Array или подклассом Float32Array и они будут из той же области (свободно, окно), что и код, который вы проверяете, посмотрите ответ Антона с помощью instanceof.

Если вам нужно знать, что это именно Float32Array а не подкласс (и он из той же области), вы можете использовать yourObject.constructor === Float32Array:

if (yourObject.constructor === Float32Array) {
     // It 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
}

Ответ 2

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

Ответ 3

Вы также можете использовать конструкцию yourObject instanceof Float32Array. Он возвращает true, если ваш объект является экземпляром Float32Array и false в другом случае.

if (yourObject instanceof Float32Array) {
    // your code here
}

Ответ 4

Если вам нужен более общий тест, который ловит любые типы ArrayBufferView и DataView, вы можете использовать:

if (Object.prototype.toString.call(yourObject.buffer) === "[object ArrayBuffer]") {
     // It either an ArrayBufferView or a DataView
}

Ответ 5

Я удивлен, что никто не получил этого ниже. Это должно работать в большинстве случаев, чтобы выяснить, есть ли у вас типизированный массив:

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 или аналогичный - лучший способ узнать наверняка для определенных типов.

Ответ 6

Все типизированные массивы наследуются от ArrayBuffer. Этот тип содержит свойство byteLength, поэтому просто проверьте, доступно ли это свойство.

function isTypedArray(obj)
{
    return !!obj && obj.byteLength !== undefined;
}