跳到主要内容

เนื้อหาภาษาไทย / 泰语内容

系统指南 内容已审核

Proxy Object

Proxy Object: ควบคุมการเข้าถึง Object อย่างมืออาชีพ

ในโลกของการพัฒนา JavaScript, การควบคุมการเข้าถึงและแก้ไข Object เป็นสิ่งสำคัญอย่างยิ่ง โดยเฉพาะอย่างยิ่งเมื่อทำงานกับข้อมูลที่ละเอียดอ่อน หรือต้องการเพิ่มความปลอดภัยให้กับการทำงานของโค้ด บทความนี้จะแนะนำ Proxy Object ซึ่งเป็นเครื่องมือที่ช่วยให้คุณสามารถควบคุมการเข้าถึง Object ได้อย่างละเอียดและมีประสิทธิภาพ

ก่อนที่เราจะไปต่อ ลองนึกภาพว่าคุณมีบ้าน (Object) และต้องการให้คนอื่น (โค้ดส่วนอื่น) เข้ามาใช้สิ่งของในบ้านได้ แต่คุณต้องการควบคุมว่าใครสามารถเข้าถึงห้องไหน (Properties) ได้บ้าง และสามารถทำอะไรได้บ้าง (อ่าน, แก้ไข) Proxy เปรียบเสมือน "ยาม" ที่คอยเฝ้าบ้านของคุณ และอนุญาตหรือไม่อนุญาตให้คนเข้าบ้านตามกฎที่คุณกำหนด

Proxy Object คืออะไร?

Proxy Object เป็น Object ที่ทำหน้าที่เป็นตัวกลางระหว่าง Object เป้าหมาย (Target Object) และการเข้าถึง Object นั้นจากภายนอก Proxy ช่วยให้คุณสามารถดักจับ (intercept) และปรับเปลี่ยนการทำงานเมื่อมีการเข้าถึง Object เป้าหมาย เช่น การอ่านค่า, การเขียนค่า, การเรียกใช้ method เป็นต้น

กล่าวอีกนัยหนึ่ง, Proxy สร้าง "ภาพสะท้อน" ของ Object เดิม แต่คุณสามารถกำหนดกฎเกณฑ์ในการเข้าถึง "ภาพสะท้อน" นี้ได้ ซึ่งจะส่งผลต่อการทำงานของ Object เดิม

การสร้าง Proxy Object

การสร้าง Proxy Object ทำได้โดยใช้ constructor ของ Proxy ซึ่งรับพารามิเตอร์สองตัว:

  1. Target Object: Object ที่คุณต้องการควบคุมการเข้าถึง
  2. Handler Object: Object ที่มี methods (traps) ที่กำหนดวิธีการทำงานเมื่อมีการเข้าถึง Target Object
const target = {
  name: "John Doe",
  age: 30,
};

const handler = {
  // Traps จะถูกกำหนดใน Handler Object
};

const proxy = new Proxy(target, handler);

ในตัวอย่างข้างต้น, target คือ Object ที่เราต้องการควบคุมการเข้าถึง และ handler คือ Object ที่เราจะกำหนดกฎเกณฑ์ในการเข้าถึง target ผ่าน proxy

Handlers: หัวใจของการควบคุม

Handler Object เป็นส่วนที่สำคัญที่สุดของ Proxy เพราะเป็นที่ที่เรากำหนดวิธีการทำงานเมื่อมีการเข้าถึง Target Object Handler Object ประกอบด้วย methods ที่เรียกว่า "traps" ซึ่งแต่ละ trap จะถูกเรียกใช้เมื่อมีการกระทำบางอย่างเกิดขึ้นกับ Object เป้าหมาย

ต่อไปนี้คือ traps ที่สำคัญบางส่วน:

  • get(target, property, receiver): ถูกเรียกเมื่อมีการอ่านค่า property ของ Object เป้าหมาย
  • set(target, property, value, receiver): ถูกเรียกเมื่อมีการเขียนค่า property ของ Object เป้าหมาย
  • has(target, property): ถูกเรียกเมื่อใช้ in operator เพื่อตรวจสอบว่า Object เป้าหมายมี property นั้นหรือไม่
  • deleteProperty(target, property): ถูกเรียกเมื่อใช้ delete operator เพื่อลบ property ของ Object เป้าหมาย
  • apply(target, thisArg, argumentsList): ถูกเรียกเมื่อ Object เป้าหมายเป็น function และถูกเรียกใช้งาน
  • construct(target, argumentsList, newTarget): ถูกเรียกเมื่อ Object เป้าหมายเป็น constructor และถูกเรียกใช้งานด้วย new operator

ตัวอย่าง: การใช้ get trap

const target = {
  name: "John Doe",
  age: 30,
};

const handler = {
  get: function(target, property, receiver) {
    console.log(`กำลังเข้าถึง property: ${property}`);
    return Reflect.get(target, property, receiver);
  },
};

const proxy = new Proxy(target, handler);

console.log(proxy.name); // Output: กำลังเข้าถึง property: name
                         //         John Doe

ในตัวอย่างนี้, เมื่อเราพยายามเข้าถึง proxy.name, get trap จะถูกเรียกใช้งาน ก่อนที่จะคืนค่า name จริงๆ ของ target เราได้ทำการ logging ข้อความ "กำลังเข้าถึง property: name" ออกมา

สำคัญ: ใน trap ส่วนใหญ่ เราใช้ Reflect API ในการส่งต่อการทำงานไปยัง Object เป้าหมาย Reflect API เป็น API ที่มี methods ที่สอดคล้องกับ operators และ functions ใน JavaScript ทำให้เราสามารถควบคุมการทำงานของ Object ได้อย่างละเอียดและปลอดภัย

ตัวอย่าง: การใช้ set trap เพื่อ validation

const target = {
  age: 30,
};

const handler = {
  set: function(target, property, value, receiver) {
    if (property === 'age') {
      if (typeof value !== 'number' || value < 0) {
        throw new Error('Age must be a positive number.');
      }
    }
    return Reflect.set(target, property, value, receiver);
  },
};

const proxy = new Proxy(target, handler);

proxy.age = 35; // ทำงานได้ปกติ
// proxy.age = -5; // จะ throw Error: Age must be a positive number.
// proxy.age = "abc"; // จะ throw Error: Age must be a positive number.

ในตัวอย่างนี้, เราใช้ set trap เพื่อตรวจสอบว่าค่าที่กำลังจะถูกกำหนดให้กับ age property เป็นตัวเลขบวกหรือไม่ ถ้าไม่เป็นไปตามเงื่อนไข เราจะ throw Error ออกมา

กรณีใช้งานจริงและข้อผิดพลาดที่พบบ่อย

Proxy Object มีประโยชน์อย่างมากในการพัฒนา JavaScript นี่คือบางกรณีใช้งานจริง:

  • Validation: ตรวจสอบความถูกต้องของข้อมูลก่อนที่จะถูกกำหนดให้กับ Object
  • Logging: บันทึกการเข้าถึงและแก้ไข Object เพื่อติดตามการทำงานของโค้ด
  • Authorization: จำกัดการเข้าถึง Object ตามสิทธิ์ของผู้ใช้งาน
  • Caching: เก็บผลลัพธ์ของการคำนวณที่ซับซ้อนไว้ใน cache เพื่อเพิ่มประสิทธิภาพ
  • Data Binding: เชื่อมโยงข้อมูลระหว่าง UI และ Object โดยอัตโนมัติ

ข้อผิดพลาดที่พบบ่อย:

  • ลืมใช้ Reflect API: การไม่ใช้ Reflect API ใน trap อาจทำให้เกิดพฤติกรรมที่ไม่คาดฝัน
  • การวนลูปไม่รู้จบ: หาก trap พยายามเข้าถึง property ที่ตัวเองกำลังดักจับ อาจทำให้เกิดการวนลูปไม่รู้จบ
  • การจัดการ Error ที่ไม่เหมาะสม: การไม่จัดการ Error ใน trap อย่างเหมาะสมอาจทำให้โปรแกรมหยุดทำงาน

ตัวอย่าง: การ Logging การเข้าถึง Object

const log = [];

const target = {
  a: 1,
  b: 2,
};

const handler = {
  get: function(target, prop, receiver) {
    log.push(`GET ${prop}`);
    return Reflect.get(target, prop, receiver);
  },
  set: function(target, prop, value, receiver) {
    log.push(`SET ${prop} = ${value}`);
    return Reflect.set(target, prop, value, receiver);
  }
};

const proxy = new Proxy(target, handler);

proxy.a; // log.push('GET a')
proxy.b = 3; // log.push('SET b = 3')

console.log(log); // Output: ["GET a", "SET b = 3"]

ในตัวอย่างนี้, เราใช้ get และ set traps เพื่อบันทึกการเข้าถึงและแก้ไข properties ของ Object ลงใน log array

สรุป

Proxy Object เป็นเครื่องมือที่มีประสิทธิภาพในการควบคุมการเข้าถึง Object ใน JavaScript ช่วยให้คุณสามารถเพิ่มความปลอดภัย, ตรวจสอบความถูกต้องของข้อมูล, และติดตามการทำงานของโค้ดได้อย่างละเอียด การเข้าใจและใช้งาน Proxy Object จะช่วยให้คุณเขียนโค้ดที่มีคุณภาพและบำรุงรักษาได้ง่ายขึ้น

ในบทความถัดไป เราจะพูดถึง Reflect API ซึ่งเป็นคู่หูที่สำคัญของ Proxy Object และช่วยให้เราสามารถควบคุมการทำงานของ Object ได้อย่างละเอียดมากยิ่งขึ้น

Office.in.th Custom Service

想基于此结构开发或定制系统?

Office.in.th 承接企业级 Web Application、API Integration 以及政府/企业管理系统的设计与开发,并提供长期支持。

查看软件开发服务