อยากให้ JavaScript มี keyword final แบบ Java ต้องทำอย่างไร
สวัสดีท่านผู้อ่านทุกท่าน สำหรับท่านใดที่คุ้นเคยกับภาษา Java มาก่อน ก็จะรู้ว่าเราสามารถกำหนด type ของตัวแปรให้เป็น final ได้ ซึ่งเจ้า final นี้เองที่ทำให้ code ของเราคงคุณสมบัติ closed ต่อการเปลี่ยนแปลง ไม่อนุญาตให้เพิ่ม ลด แก้ไข ซึ่งช่วยลดโอกาสการเกิดบัคในอนาคตได้ด้วย
วันนี้เราจะมานำเสนอวิธีดังกล่าวในของภาษา JavaScript กันครับ ไปดูกันเลย
ใน ECMAScript 5 นั้น คลาส Object มี method ให้เรียกได้นั่นคือ Object.freeze(), Object.seal() และ Object.preventExtensions() ซึ่งผมจะอธิบายรายตัวเลยเริ่มจาก
Object.freeze()
หลายคนเดาได้จากชื่อเลยครับ ก็คือเป็นเหมือนการแช่แข็ง object นั้น โดยไม่อนุญาตให้เปลี่ยนแปลง(ลบ/เพิ่ม/แก้ไข)ใดๆได้เลย
ส่วน method สำหรับใช้ตรวจสอบว่า object นั้นถูกแช่แข็งอยู่หรือไม่ ก็คือ Object.isFrozen()
ตัวอย่าง
let cat = {
name: "Malee",
gender: "female",
};Object.freeze(cat);
Object.isFrozen(cat); // return truecat.breed = "Persian";
console.log(cat.breed); // return undefinedcat.name = "Mali";
console.log(cat); // return { name: "Malee", gender: "female" }delete cat.name;
console.log(cat); // return { name: "Malee", gender: "female" }
Object.seal()
เป็นเหมือนการแพ็ค ซีลของไว้ไม่ให้เพิ่มไม่ให้ลด คือไม่อนุญาตให้ เพิ่ม properties ใหม่ๆ หรือลบ properties ที่มีอยู่แล้วได้เลย แต่ยังอนุญาตให้สามารถแก้ไข properties ที่มีอยู่แล้วได้
method สำหรับใช้ตรวจสอบว่า object นั้นถูก seal อยู่หรือไม่ คือ Object.isSealed()
ตัวอย่าง
let cat = {
name: "Malee",
gender: "female",
};Object.seal(cat);
Object.isSealed(cat); // return true//Type error
cat.breed = "Persian";
console.log(cat.breed); // return undefinedcat.name = "Mali";
console.log(cat); // return { name: "Mali", gender: "female" }delete cat.name;
console.log(cat); // return { name: "Mali", gender: "female" }
//TypeError
Object.defineProperty(cat, "name", {
get: () => "Nomyen",
});
Object.preventExtensions()
ชื่อตรงไปตรงมาที่สุด เป็นการห้ามไม่ให้ Object มี properties ใหม่ แต่สามารถแก้หรือลบ properties ที่มีอยู่ได้ นั่นเอง
method ที่ใช้ตรวจสอบว่า Object สามารถเพิ่ม properties ใหม่ได้หรือไม่ Object.isExtensible()
ตัวอย่าง
let cat = {
name: "Malee",
gender: "female",
};Object.preventExtensions(cat);
Object.isExtensible(cat); // return falsecat.breed = "Persian";
console.log(cat.breed); // return undefinedcat.name = "Mali";
console.log(cat); // return { name: "Mali", gender: "female" }delete cat.name;
console.log(cat); // return { gender: "female" }
สรุป
ข้อจำกัด
ทั้งสาม method ข้างต้นนั้น เป็นการห้ามแบบ shallowly หมายความว่า สามารถห้ามได้เฉพาะ property ที่เข้าถึงได้ในชั้นแรกเท่านั้น ส่วน property ที่เป็น Object ซ้อน หรือแบบ nested นั้น จะไม่สามารถห้ามได้