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

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

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

เมธอด DataView.prototype.setUint16() ใช้สำหรับ เขียนค่าจำนวนเต็มไม่มีเครื่องหมาย 16-bit (unsigned 16-bit integer) ลงในตำแหน่งที่กำหนดใน DataView ค่าที่เขียนได้จะอยู่ในช่วง 0 ถึง 65,535 (0x0000 - 0xFFFF)

ไวยากรณ์ (Syntax)

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

คืนค่า: undefined

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

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

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

view.setUint16(0, 45544); // big-endian default
console.log(view.getUint16(0)); // 45544

ตัวอย่างที่ 2: Endianness Handling

const buffer = new ArrayBuffer(4);
const view = new DataView(buffer);
const value = 0x1234; // 4660

view.setUint16(0, value, false); // big-endian: 0x12, 0x34
view.setUint16(2, value, true);  // little-endian: 0x34, 0x12

console.log('BE:', view.getUint16(0, false).toString(16)); // 1234
console.log('LE:', view.getUint16(2, true).toString(16));  // 1234

// Raw bytes
const bytes = new Uint8Array(buffer);
console.log(Array.from(bytes).map(b => b.toString(16).padStart(2, '0')));
// ['12', '34', '34', '12']

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

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

view.setUint16(0, 65536); // 2^16
console.log(view.getUint16(0)); // 0 (wrap around)

view.setUint16(0, 65535); // max
console.log(view.getUint16(0)); // 65535

view.setUint16(0, -1); // negative -> wrap
console.log(view.getUint16(0)); // 65535

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

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

view.setUint16(0, 455.44); // truncate -> 455
console.log(view.getUint16(0)); // 455

ตัวอย่างที่ 5: Port Number Packing (Network Programming)

function packPort(port) {
  if (port < 0 || port > 65535) throw new Error('Invalid port');
  const buffer = new ArrayBuffer(2);
  const view = new DataView(buffer);
  view.setUint16(0, port, false); // Network byte order = big-endian
  return new Uint8Array(buffer);
}

function unpackPort(bytes) {
  const view = new DataView(bytes.buffer, bytes.byteOffset, 2);
  return view.getUint16(0, false);
}

console.log(packPort(80));    // Uint8Array [0, 80]
console.log(packPort(443));   // Uint8Array [1, 187]
console.log(packPort(8080));  // Uint8Array [31, 144]
console.log(unpackPort(packPort(3000))); // 3000

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

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

Endianness สำคัญอย่างไร

สำหรับ 16-bit (2 bytes) endianness กำหนดลำดับไบต์:

  • Big-endian (Network order): High byte first - ใช้ใน network protocols (TCP/UDP ports, IP headers)
  • Little-endian: Low byte first - ใช้ใน CPU architecture (x86, ARM)
// ค่า 0x1234 (4660)
// Big-endian:  [0x12, 0x34] -> getUint16(0, false) = 4660
// Little-endian: [0x34, 0x12] -> getUint16(0, true) = 4660

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

  • Network protocols: TCP/UDP port numbers, DNS message IDs, checksums
  • File formats: BMP (width/height), TIFF, WAV (sample rate, channels)
  • Image processing: 16-bit grayscale, color channels
  • Sensor data: 12/14-bit ADC values stored in 16-bit
  • Audio: 16-bit PCM (แต่เป็น signed มากกว่า)
  • Unicode: UTF-16 code units (BMP characters)

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

  • โยน RangeError หาก byteOffset ติดลบ หรือ byteOffset + 2 > byteLength
  • ค่า value จะถูกแปลงด้วย ToUint16 (modulo 65536)
  • Endianness ต้องตรงกับที่อ่าน (getUint16) มิฉะนั้นจะได้ค่าผิด