Как найти тип typedArray? - PullRequest
       51

Как найти тип typedArray?

1 голос
/ 08 октября 2019

Чтобы проверить, является ли объект массивом, существует метод -

const myarray = [1,2,3,4]; 
Array.isArray(myarray); 
//returns true

Существует ли аналогичный метод для типизированных массивов (например, Uint8Array)?

const int8 = new Uint8Array([0,1,2,3]);
Array.isArray(int8); //returns false

Как узнать, является ли объект типизированным массивом и какой тип типизированного массива?

Ответы [ 4 ]

2 голосов
/ 08 октября 2019

instanceof кажется лучшим выбором, однако конструктор TypedArray отсутствует, поэтому это означает, что нам нужно протестировать все возможные конструкторы TypedArrays независимо.

const typedArrays = [
 'Int8',
 'Uint8',
 'Uint8Clamped',
 'Int16',
 'Uint16',
 'Int32',
 'Uint32',
 'Float32',
 'Float64',
 'BigInt64',
 'BigUint64'
].map( (pre) => pre + 'Array' );

function getType( arr ) {
  return typedArrays.find( (type) => arr instanceof window[ type ] );
}
function isTypedArray( arr ) {
  return getType( arr ) !== undefined;
}

const uint8 = new Uint8Array([0,1,2,3]);
const int16 = new Int16Array([0,1,2,3])
const float32 = new Float32Array([0,1,2,3])

console.log( 'uint8', getType( uint8 ) );
console.log( 'int16', getType( int16 ) );
console.log( 'float32', getType( float32 ) );
console.log( "is TypedArray []", isTypedArray([0,1,2,3]) );
console.log( "is TypedArray int16", isTypedArray(int16) );
1 голос
/ 08 октября 2019

Другой подход может быть следующим: вы можете использовать BYTES_PER_ELEMENT свойство типизированного массива

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/BYTES_PER_ELEMENT

Array.isTypedArray = function(inArray) {
  if (inArray) {
    const prototype = Object.getPrototypeOf(inArray);
    return prototype ? prototype.hasOwnProperty("BYTES_PER_ELEMENT") : false;
  }
  return false;
};

Как уже упоминалось в других ответах, чтобы получить фактический тип, вы можете использовать constructor.name. Повторно используя вышеуказанную функцию isTypedArray, вы можете написать так:

function getType(obj){
    return Array.isTypedArray(obj) ? obj.constructor.name: (typeof obj)
}

Пример кода & console.logs

Array.isTypedArray = function(inArray){
    if(inArray){
        const prototype = Object.getPrototypeOf(inArray);
        return prototype ? prototype.hasOwnProperty("BYTES_PER_ELEMENT") : false;
    }
    return false;
}

console.log(" 'Iam' a typed array ? ", Array.isTypedArray([1,2,3]));
console.log("[1,2,3] is typed array ? ", Array.isTypedArray([1,2,3]));
console.log("new Int8Array([1,2,3]) is typed array ? ", Array.isTypedArray(new Int8Array([1,2,3])));
console.log("new BigUint64Array() is typed array ? ", Array.isTypedArray(new BigUint64Array()));
console.log("new Uint8ClampedArray([1,2,3]) is typed array ? ", Array.isTypedArray(new Uint8ClampedArray([1,2,3])));
console.log("new Float32Array([1,2,3]) is typed array ? ", Array.isTypedArray(new Float32Array([1,2,3])));
console.log("new BigUint64Array() is typed array ? ", Array.isTypedArray(new BigUint64Array()));
console.log("new Set() is typed array ? ", Array.isTypedArray(new Set()));
console.log("null is typed array ? ", Array.isTypedArray(null));
console.log("undedined is typed array ? ", Array.isTypedArray(undefined));
console.log("{} is typed array ? ",Array.isTypedArray({}));


function getType(obj){
    return Array.isTypedArray(obj) ? obj.constructor.name: (typeof obj)
}

console.log("Type of Array ? ", getType(new Array()));
console.log("Type of Int8Array ? ", getType(new Int8Array()));
console.log("Type of Uint8Array ? ",getType( new Uint8Array()));
console.log("Type of Uint8ClampedArray ? ",getType( new Uint8ClampedArray()));
console.log("Type of Int16Array ? ", getType(new Int16Array()));
console.log("Type of Float32Array ? ", getType(new Float32Array()));
console.log("Type of BigInt64Array ? ", getType(new BigInt64Array()));
console.log("Type of BigUint64Array ? ", getType(new BigUint64Array()));
1 голос
/ 08 октября 2019

Вы можете использовать сравнение с его конструктором 1 :

const int8 = new Uint8Array([0,1,2,3]);
console.log(int8.constructor === Uint8Array);

// so you can do
function checkTypedArrayType(someTypedArray) {
  const typedArrayTypes = [
    Int8Array,
    Uint8Array,
    Uint8ClampedArray,
    Int16Array,
    Uint16Array,
    Int32Array,
    Uint32Array,
    Float32Array,
    Float64Array,
    BigInt64Array,
    BigUint64Array
  ];
  const checked = typedArrayTypes.filter(ta => someTypedArray.constructor === ta);
  return checked.length && checked[0].name || null;
}

console.log(checkTypedArrayType(int8));

// but this can be hugely simplified
function checkTypedArrayType2(someTypedArray) {
  return someTypedArray && 
    someTypedArray.constructor && 
    someTypedArray.constructor.name || 
    null;
}

console.log(checkTypedArrayType2(int8));

// which can actually be generalized to
const whatsMyType = someObject => 
  someObject && 
    someObject.constructor && 
    someObject.constructor.name && 
    someObject.constructor.name || 
    null;

console.log(whatsMyType(int8));
console.log(whatsMyType([1,2,3,4]));
console.log(whatsMyType("hello!"))
console.log(whatsMyType(/[a-z]/i))

1 Обратите внимание, что ни одна версия Internet Explorer не поддерживает свойство name. См. MDN . См. Также

0 голосов
/ 08 октября 2019

Вы можете использовать свойство .name для него. Он должен возвращать тип: "Uint8Array". Это работает и с Uint16, и с Unint32.

MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/name

Редактировать: добавить источник

...