ArrayBuffer.slice() คืออะไร?
ArrayBuffer.prototype.slice(begin, end) สร้าง ArrayBuffer ใหม่ ที่เป็นสำเนาของข้อมูลบाइनะรี่จากตำแหน่ง begin (inclusive) ถึง end (exclusive) คล้ายกับ Array.slice() แต่ทำงานกับ binary data
Syntax
arrayBuffer.slice(begin[, end])
begin- index เริ่มต้น (0-based) รวมตัวเองend(optional) - index สิ้นสุด ไม่รวมตัวเอง | default = byteLength- คืนค่า: ArrayBuffer ใหม่ (ไม่เปลี่ยนตัวเดิม)
- รองรับ negative index (นับจากท้าย)
ตัวอย่างโค้ดครบถ้วน
<!DOCTYPE html>
<html lang="th">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>ArrayBuffer.slice() 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; }
button:hover { background: #6a1b9a; }
table { width: 100%; border-collapse: collapse; margin-top: 10px; }
th, td { padding: 8px; border: 1px solid #ddd; text-align: center; }
th { background: #7e32d4; color: white; }
</style>
</head>
<body>
<h1>ArrayBuffer.slice() Demo</h1>
<div class="panel">
<h3>สร้าง ArrayBuffer 16 bytes (4 จำนวน Int32)</h3>
<button onclick="createBuffer()">สร้าง Buffer ใหม่</button>
<button onclick="demoSlice()">Slice (0, 8) - copy 8 bytes แรก</button>
<button onclick="demoSliceNegative()">Slice (-8) - copy 8 bytes หลัง</button>
<button onclick="demoSliceRange()">Slice (4, 12) - copy กลาง</button>
</div>
<div class="panel">
<h3>Original Buffer (Int32 View)</h3>
<div class="code" id="originalView"></div>
</div>
<div class="panel">
<h3>Sliced Buffer Result</h3>
<div class="output" id="slicedOutput"></div>
</div>
<script>
let buffer = null;
let int32View = null;
const originalView = document.getElementById('originalView');
const slicedOutput = document.getElementById('slicedOutput');
function createBuffer() {
buffer = new ArrayBuffer(16); // 16 bytes = 4 Int32 (4 bytes each)
int32View = new Int32Array(buffer);
int32View[0] = 0x11223344;
int32View[1] = 0x55667788;
int32View[2] = 0x99AABBCC;
int32View[3] = 0xDDEEFF00;
originalView.textContent = 'Buffer byteLength: ' + buffer.byteLength + '\n' +
'Int32Array: [' + Array.from(int32View).map(v => '0x' + v.toString(16).toUpperCase().padStart(8, '0')).join(', ') + ']';
slicedOutput.textContent = 'ยังไม่ได้ slice';
}
function showSliceResult(slicedBuffer, label) {
const view = new Int32Array(slicedBuffer);
slicedOutput.textContent = `${label}\n` +
`byteLength: ${slicedBuffer.byteLength} bytes\n` +
`Int32Array: [${Array.from(view).map(v => '0x' + v.toString(16).toUpperCase().padStart(8, '0')).join(', ')}]`;
}
function demoSlice() {
if (!buffer) { alert('สร้าง Buffer ก่อน'); return; }
// copy 8 bytes แรก (2 Int32 แรก)
const sliced = buffer.slice(0, 8);
showSliceResult(sliced, 'slice(0, 8) - 8 bytes แรก:');
}
function demoSliceNegative() {
if (!buffer) { alert('สร้าง Buffer ก่อน'); return; }
// copy 8 bytes หลัง (2 Int32 หลัง) - negative index
const sliced = buffer.slice(-8);
showSliceResult(sliced, 'slice(-8) - 8 bytes หลัง:');
}
function demoSliceRange() {
if (!buffer) { alert('สร้าง Buffer ก่อน'); return; }
// copy bytes 4-11 (Int32 index 1 และ 2)
const sliced = buffer.slice(4, 12);
showSliceResult(sliced, 'slice(4, 12) - bytes 4-11:');
}
createBuffer();
</script>
</body>
</html>
การทำงานของ Slice
Original Buffer (16 bytes): Index: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Value: 44 33 22 11 88 77 66 55 CC BB AA 99 00 FF EE DD (Little Endian) Int32 View: [0x11223344, 0x55667788, 0x99AABBCC, 0xDDEEFF00] slice(0, 8) → bytes 0-7 → Int32: [0x11223344, 0x55667788] (2 elements) slice(4, 12) → bytes 4-11 → Int32: [0x55667788, 0x99AABBCC] (2 elements) slice(-8) → bytes 8-15 → Int32: [0x99AABBCC, 0xDDEEFF00] (2 elements) slice() → bytes 0-15 → Int32: [0x11223344, 0x55667788, 0x99AABBCC, 0xDDEEFF00] (copy ทั้งหมด)
กรณีการใช้งานจริง (Use Cases)
- Binary Protocol Parsing: ตัด header/payload ออกจาก buffer ที่รับมาจาก network
- File Processing: อ่านเฉพาะส่วนของไฟล์ใหญ่ (chunked reading)
- WebGL/WebGPU: สร้าง sub-buffer สำหรับ vertex/index buffers
- Audio/Video: ตัด frame หรือ sample จาก buffer
- Crypto: แยก salt, IV, ciphertext จาก encrypted buffer
ความแตกต่างกับ TypedArray.subarray()
| คุณสมบัติ | ArrayBuffer.slice() | TypedArray.subarray() |
|---|---|---|
| คืนค่า | ArrayBuffer ใหม่ (copy ข้อมูล) | TypedArray view ใหม่ (shared memory - zero copy) |
| Memory | จองหน่วยความจำใหม่ | ไม่จองหน่วยความจำใหม่ (เร็วกว่า) |
| ใช้เมื่อ | ต้องการ buffer แยกต่างหาก (isolated) | ต้องการ view ตัวแปรของข้อมูลเดิม |
| Available on | ArrayBuffer | Int8Array, Uint8Array, Int32Array, Float32Array, etc. |
ตัวอย่าง subarray (Zero-copy)
const buffer = new ArrayBuffer(16); const view = new Int32Array(buffer); view[0] = 1; view[1] = 2; view[2] = 3; view[3] = 4; const sub = view.subarray(1, 3); // Int32Array [2, 3] - ใช้ memory เดียวกัน! sub[0] = 999; console.log(view[1]); // 999 - เปลี่ยนค่าตัวเดิมด้วย!