Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> JavaScript

ฟังก์ชัน DataView.setUint32() ใน JavaScript

DataView.setUint32() คืออะไร

เมธอด DataView.prototype.setUint32() ใช้สำหรับ เขียนค่าจำนวนเต็มไม่มีเครื่องหมาย 32-bit (unsigned 32-bit integer) ลงในตำแหน่งที่กำหนดใน DataView ค่าที่เขียนได้จะอยู่ในช่วง 0 ถึง 4,294,967,295 (0x00000000 - 0xFFFFFFFF)

ไวยากรณ์ (Syntax)

dataView.setUint32(byteOffset, value [, littleEndian])
  • byteOffset - ตำแหน่งเริ่มต้นในหน่วยไบต์ (0-indexed)
  • value - ค่าที่จะเขียน (0 ถึง 4294967295)
  • littleEndian (optional) - true = little-endian, false = big-endian (default: false)

คืนค่า: undefined

ตัวอย่างการใช้งาน

ตัวอย่างที่ 1: การเขียนและอ่านค่าพื้นฐาน

const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);

view.setUint32(0, 45544); // big-endian default
console.log(view.getUint32(0)); // 45544

ตัวอย่างที่ 2: การจัดการ Endianness

const buffer = new ArrayBuffer(8);
const view = new DataView(buffer);
const value = 0x12345678; // 305419896

// เขียน big-endian (network byte order)
view.setUint32(0, value, false);
// เขียน little-endian (CPU native)
view.setUint32(4, value, true);

console.log('BE:', view.getUint32(0, false).toString(16)); // 12345678
console.log('LE:', view.getUint32(4, true).toString(16));  // 12345678

// Raw bytes
const bytes = new Uint8Array(buffer);
console.log('Bytes:', Array.from(bytes).map(b => b.toString(16).padStart(2, '0')));
// BE: 12, 34, 56, 78 | LE: 78, 56, 34, 12

ตัวอย่างที่ 3: การจัดการค่าที่ล้น (Overflow / Wrap-around)

const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);

// ค่าที่ใหญ่เกิน max uint32 จะ wrap around (modulo 2^32)
view.setUint32(0, 4294967296); // 2^32
console.log(view.getUint32(0)); // 0

view.setUint32(0, 4294967295); // max uint32
console.log(view.getUint32(0)); // 4294967295

view.setUint32(0, -1); // ติดลบ -> wrap around
console.log(view.getUint32(0)); // 4294967295 (0xFFFFFFFF)

ตัวอย่างที่ 4: การแปลงค่า Float

const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);

view.setUint32(0, 455.44); // ตัดทศนิยม -> 455
console.log(view.getUint32(0)); // 455

ตัวอย่างที่ 5: IPv4 Address Packing

function ipToUint32(ip) {
  const parts = ip.split('.').map(Number);
  if (parts.length !== 4 || parts.some(p => p < 0 || p > 255)) {
    throw new Error('Invalid IPv4 address');
  }
  // Big-endian (network order)
  return (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8) | parts[3];
}

function uint32ToIp(num) {
  return [
    (num >>> 24) & 0xFF,
    (num >>> 16) & 0xFF,
    (num >>> 8) & 0xFF,
    num & 0xFF
  ].join('.');
}

const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);

const ip = '192.168.1.1';
const packed = ipToUint32(ip);
view.setUint32(0, packed, false); // Network byte order = big-endian

console.log('Packed:', packed); // 3232235777
console.log('Unpacked:', uint32ToIp(view.getUint32(0, false))); // 192.168.1.1

ตัวอย่างที่ 6: อ่านค่าที่ยังไม่ได้ตั้งค่า

const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
console.log(view.getUint32(0)); // 0

Endianness และการใช้งาน

Endiannessค่า littleEndianใช้เมื่อไหร่
Big-endian (Network byte order)false (default)Network protocols (IP, TCP, DNS), File formats (PNG, JPEG)
Little-endiantruex86/x64 memory, WebAssembly, WASI, บาง file formats

กรณีการใช้งานทั่วไป

  • Network programming: IPv4 addresses, packet headers, sequence numbers
  • File formats: PNG (chunk lengths), ZIP, MP4, ELF headers
  • Graphics: Texture data, vertex indices (32-bit)
  • Hash/Checksum: CRC32, Adler-32, partial MD5/SHA
  • WebAssembly interop: รับส่ง i32/u32
  • ID generation: 32-bit unique identifiers

กรณีพิเศษและข้อผิดพลาด

  • โยน RangeError หาก byteOffset ติดลบ หรือ byteOffset + 4 > byteLength
  • ค่า value จะถูกแปลงด้วย ToUint32 (modulo 2^32)
  • ไม่รองรับ BigInt โดยตรง - ต้องแปลงเป็น Number ก่อน (อาจสูญเสีย precision สำหรับค่า > 2^53)