私はゲームに取り組んでおり、数学型には型付き配列(Float32Arrays)を多用しています。 JSONからgamestateを保存してロードします。 JSON stringify出力の例は、そのような配列(Chromeの場合)の場合です。
"{"0":0,"1":0,"2":0,"length":3,"byteLength":12,"byteOffset":0,"buffer":{"byteLength":12}}"
これはスペースを浪費し、それらをオブジェクトとしてロードする原因となり、不便です。理想的には、stringify'replacer '関数を使用して、変数が型付き配列であるかどうかをテストし、その場合はそれをbog標準配列に変換できます。残念ながら、変数が型付き配列であるかどうかを確実にテストする方法がわかりません。
何か助けはありますか?
Float32Array
またはFloat32Array
のサブクラスであることに満足している場合、それらは同じからのものになります- レルム(大まかに、ウィンドウ)チェックしているコードとして instanceof
を使用したAntonの回答を参照 。
それが具体的に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));
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
yourObject instanceof Float32Array
構文を使用することもできます。オブジェクトがFloat32Array
のインスタンスである場合はtrue
を返し、それ以外の場合はfalse
を返します。
if (yourObject instanceof Float32Array) {
// your code here
}
誰もこれを下に持っていないことに驚いています。これは、ほとんどの場合、型付き配列があるかどうかを判断するために機能するはずです。
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
または同様のものは、特定のタイプを確実に知るための最良の方法です。
ArrayBufferViewおよびDataViewタイプのいずれかをキャッチするより一般的なテストが必要な場合は、次を使用できます。
if (Object.prototype.toString.call(yourObject.buffer) === "[object ArrayBuffer]") {
// It's either an ArrayBufferView or a DataView
}
型指定された配列はすべてArrayBufferから継承されます。このタイプにはbyteLengthプロパティが含まれているため、このプロパティが使用可能かどうかを簡単に確認してください。
function isTypedArray(obj)
{
return !!obj && obj.byteLength !== undefined;
}