ArrayBuffer.isView() คืออะไร?
ArrayBuffer.isView(arg) เป็น static method ที่ตรวจสอบว่า argument ที่ส่งเข้ามาเป็น ArrayBuffer View (TypedArray หรือ DataView) หรือไม่ คืนค่า true / false
ArrayBuffer Views ที่ตรวจสอบได้
- TypedArrays: Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array, BigInt64Array, BigUint64Array
- DataView
- ไม่รวม: ArrayBuffer ตัวเอง, plain Array, Object, null, undefined
ตัวอย่างโค้ดครบถ้วน
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ArrayBuffer.isView() Demo</title>
<style>
body { font-family: 'Segoe UI', sans-serif; padding: 20px; max-width: 800px; margin: 0 auto; }
.panel { background: #f5f5f5; padding: 20px; border-radius: 8px; margin-bottom: 20px; }
.code { background: #2d2d2d; color: #f8f8f2; padding: 15px; border-radius: 4px; font-family: monospace; overflow-x: auto; }
.output { background: #e8f5e9; padding: 15px; border-radius: 4px; font-family: monospace; white-space: pre-wrap; }
button { padding: 10px 20px; background: #7e32d4; color: white; border: none; border-radius: 4px; cursor: pointer; margin-right: 10px; margin-bottom: 10px; }
button:hover { background: #6a1b9a; }
table { width: 100%; border-collapse: collapse; margin-top: 10px; }
th, td { padding: 10px; border: 1px solid #ddd; text-align: left; }
th { background: #7e32d4; color: white; }
.true { color: #2e7d32; font-weight: bold; }
.false { color: #c62828; font-weight: bold; }
</style>
</head>
<body>
<h1>ArrayBuffer.isView() - ตรวจสอบ TypedArray / DataView</h1>
<div class="panel">
<h3>ทดสอบค่าต่างๆ</h3>
<button onclick="testAll()">ทดสอบทั้งหมด</button>
<button onclick="testCustom()">ทดสtoverride Custom Object</button>
</div>
<div class="panel">
<h3>ผลลัพธ์</h3>
<div class="output" id="output"></div>
</div>
<script>
const output = document.getElementById('output');
function log(msg, isView = null) {
const div = document.createElement('div');
div.textContent = msg;
if (isView === true) div.className = 'true';
else if (isView === false) div.className = 'false';
output.appendChild(div);
}
function clear() { output.innerHTML = ''; }
function testAll() {
clear();
// สร้าง ArrayBuffer และ Views ต่างๆ
const buffer = new ArrayBuffer(16);
const testCases = [
{ name: 'ArrayBuffer (16 bytes)', value: buffer },
{ name: 'Int8Array', value: new Int8Array(buffer) },
{ name: 'Uint8Array', value: new Uint8Array(buffer) },
{ name: 'Uint8ClampedArray', value: new Uint8ClampedArray(buffer) },
{ name: 'Int16Array', value: new Int16Array(buffer) },
{ name: 'Uint16Array', value: new Uint16Array(buffer) },
{ name: 'Int32Array', value: new Int32Array(buffer) },
{ name: 'Uint32Array', value: new Uint32Array(buffer) },
{ name: 'Float32Array', value: new Float32Array(buffer) },
{ name: 'Float64Array', value: new Float64Array(buffer) },
{ name: 'BigInt64Array', value: typeof BigInt64Array !== 'undefined' ? new BigInt64Array(buffer) : 'N/A' },
{ name: 'BigUint64Array', value: typeof BigUint64Array !== 'undefined' ? new BigUint64Array(buffer) : 'N/A' },
{ name: 'DataView', value: new DataView(buffer) },
{ name: 'Plain Array []', value: [1, 2, 3] },
{ name: 'Plain Object {}', value: {} },
{ name: 'null', value: null },
{ name: 'undefined', value: undefined },
{ name: 'String', value: 'hello' },
{ name: 'Number', value: 123 },
];
log('=== ArrayBuffer.isView() Test Results ===\n');
testCases.forEach(({ name, value }) => {
if (value === 'N/A') {
log(`${name}: Not supported in this environment`);
return;
}
const result = ArrayBuffer.isView(value);
log(`${name}: ${result}`, result);
});
}
function testCustom() {
clear();
log('=== Custom Objects with Symbol.toStringTag ===\n');
// Object ปกติ - ไม่ใช่ view
const obj = {};
log(`Plain object: ${ArrayBuffer.isView(obj)}`, false);
// Object ที่ pretend เป็น TypedArray (แต่ไม่ได้จริง)
const fakeView = {
buffer: new ArrayBuffer(8),
byteLength: 8,
byteOffset: 0,
[Symbol.toStringTag]: 'Int32Array'
};
log(`Fake TypedArray (with toStringTag): ${ArrayBuffer.isView(fakeView)}`, false);
// Subclass ของ TypedArray
class MyInt32Array extends Int32Array {}
const myView = new MyInt32Array(4);
log(`MyInt32Array (extends Int32Array): ${ArrayBuffer.isView(myView)}`, true);
// DataView subclass
class MyDataView extends DataView {}
const myDV = new MyDataView(new ArrayBuffer(8));
log(`MyDataView (extends DataView): ${ArrayBuffer.isView(myDV)}`, true);
}
testAll();
</script>
</body>
</html>
ผลลัพธ์ที่คาดหวัง
ArrayBuffer (16 bytes): false
Int8Array: true
Uint8Array: true
Uint8ClampedArray: true
Int16Array: true
Uint16Array: true
Int32Array: true
Uint32Array: true
Float32Array: true
Float64Array: true
BigInt64Array: true
BigUint64Array: true
DataView: true
Plain Array []: false
Plain Object {}: false
null: false
undefined: false
String: false
Number: false
การใช้งานจริง (Use Cases)
1. Type Guard ใน TypeScript / JSDoc
function processBuffer(data: ArrayBuffer | ArrayBufferView) {
if (ArrayBuffer.isView(data)) {
// TypeScript รู้ว่า data เป็น TypedArray หรือ DataView
console.log('Byte length:', data.byteLength);
console.log('Byte offset:', data.byteOffset);
} else {
// data เป็น ArrayBuffer
console.log('Buffer size:', data.byteLength);
}
}
2. Validation ฟังก์ชันที่รับ Binary Data
function writeToBuffer(view, offset, value) {
if (!ArrayBuffer.isView(view)) {
throw new TypeError('Expected ArrayBufferView (TypedArray or DataView)');
}
if (offset < 0 || offset + 4 > view.byteLength) {
throw new RangeError('Offset out of bounds');
}
new DataView(view.buffer, view.byteOffset + offset).setInt32(0, value);
}
3. Serialize/Deserialize Binary Data
function cloneBufferView(view) {
if (!ArrayBuffer.isView(view)) {
throw new Error('Not a buffer view');
}
// สร้าง buffer ใหม่และ copy ข้อมูล
const newBuffer = new ArrayBuffer(view.byteLength);
const newView = new view.constructor(newBuffer);
newView.set(view);
return newView;
}
ความแตกต่าง: ArrayBuffer vs ArrayBufferView
| คุณสมบัติ | ArrayBuffer | ArrayBufferView (TypedArray/DataView) |
|---|---|---|
| เก็บข้อมูลจริง | ใช่ (Raw binary data) | ไม่ (Reference/Window into buffer) |
| isView() | false | true |
| byteLength | ขนาดทั้งหมด | ขนาดของ view นี้ |
| byteOffset | N/A | ตำแหน่งเริ่มต้นใน buffer |
| buffer property | N/A | อ้างอิง ArrayBuffer ต้นทาง |
| Manipulation | ไม่ได้โดยตรง | อ่าน/เขียนผ่าน TypedArray/DataView |
Browser Support
- Chrome 7+, Firefox 4+, Safari 5.1+, Edge 12+, IE 10+
- รองรับเต็มรูปแบบในทุกเบราว์เซอร์สมัยใหม่