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

คุณสมบัติ Symbol.toPrimitive ใน JavaScript: แปลง Symbol เป็นค่า Primitive

คุณสมบัติ Symbol.toPrimitive (ไม่ใช่ symbol.description ตามชื่อเรื่องเดิม) เป็น Well-known Symbol ที่ช่วยให้อ็อบเจกต์กำหนดพฤติกรรมเมื่อถูกแปลงเป็นค่า Primitive (String, Number, Default)

ไวยากรณ์ (Syntax)

object[Symbol.toPrimitive] = function(hint) {
  // hint = "string" | "number" | "default"
  // ต้องคืนค่า Primitive (string, number, boolean, null, undefined, symbol)
};

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

ตัวอย่างที่ 1: Symbol.toPrimitive พื้นฐาน

<!DOCTYPE html>
<html>
<body>
  <h2>Symbol.toPrimitive Demo</h2>
  <button onclick="display()">ทดสอบ</button>
  <p id="demo"></p>
  <script>
    function display() {
      const obj = {
        value: 42,
        [Symbol.toPrimitive](hint) {
          console.log('Hint:', hint); // "string", "number", หรือ "default"
          if (hint === 'number') return this.value;
          if (hint === 'string') return `[Object: ${this.value}]`;
          return this.value; // default
        }
      };
      
      console.log('Number:', +obj);      // 42 (hint: "number")
      console.log('String:', String(obj)); // "[Object: 42]" (hint: "string")
      console.log('Default:', obj + '');   // "42" (hint: "default")
      document.getElementById("demo").innerHTML = "ดูผลลัพธ์ใน Console (F12)";
    }
  </script>
</body>
</html>

ตัวอย่างที่ 2: Symbol Description (ชื่อเรื่องเดิม)

คุณสมบัติ Symbol.prototype.description (ES2019) ใช้สำหรับ อ่านคำอธิบาย (description) ของ Symbol เท่านั้น ไม่เกี่ยวกับการแปลงค่า

const sym1 = Symbol('my description');
const sym2 = Symbol();

console.log(sym1.description); // "my description"
console.log(sym2.description); // undefined

// Symbol() constructor ไม่สามารถเรียกด้วย new ได้
// new Symbol() // TypeError

Symbol.toPrimitive vs valueOf vs toString

เมธอดเรียกเมื่อลำดับความสำคัญ
[Symbol.toPrimitive]การแปลง Primitive ใดๆ1 (สูงสุด) - ถ้ามี จะใช้ตัวนี้
valueOf()การแปลงเป็น Number2 (ถ้าไม่มี toPrimitive)
toString()การแปลงเป็น String3 (ถ้าไม่มี toPrimitive/valueOf)
const obj = {
  valueOf() { return 10; },
  toString() { return 'hello'; },
  [Symbol.toPrimitive](hint) { return hint === 'number' ? 100 : 'primitive'; }
};

console.log(+obj);      // 100  (ใช้ Symbol.toPrimitive hint="number")
console.log(String(obj)); // "primitive" (ใช้ Symbol.toPrimitive hint="string")
console.log(obj + '');    // "primitive" (ใช้ Symbol.toPrimitive hint="default")

กรณีใช้งานจริง

// 1. Custom Object ที่ทำงานเหมือน Primitive
class Temperature {
  constructor(celsius) { this.celsius = celsius; }
  [Symbol.toPrimitive](hint) {
    if (hint === 'number') return this.celsius;
    if (hint === 'string') return `${this.celsius}°C`;
    return this.celsius;
  }
}
const temp = new Temperature(25);
console.log(+temp);       // 25
console.log(`${temp}`);   // "25°C"

// 2. Money/Currency Object
const price = {
  amount: 99.99,
  currency: 'THB',
  [Symbol.toPrimitive](hint) {
    return hint === 'string' ? `฿${this.amount}` : this.amount;
  }
};
console.log(price + 0.01); // 100 (number context)
console.log('Price: ' + price); // "Price: ฿99.99" (string context)

สรุป

  • Symbol.toPrimitive - ควบคุมการแปลงเป็น Primitive (Number/String/Default)
  • Symbol.prototype.description - อ่านคำอธิบายของ Symbol (Read-only)
  • ทั้งคู่เป็น ES6+ Features