φυβλαςのβλογ
บล็อกของ phyblas



javascript เบื้องต้น บทที่ ๒๕: การจำกัดความเปลี่ยนแปลงของออบเจ็กต์
เขียนเมื่อ 2019/08/05 10:15
แก้ไขล่าสุด 2021/09/28 16:42


จาก ES3 สู่ ES5

เนื้อหาตั้งแต่บทนี้ไปจะเป็นคำสั่งและวิธีเขียนที่ใช้ได้ตั้งแต่จาวาสคริปต์รุ่น ES5 ขึ้นไป นั่นคือถ้าใครจะเขียนจาวาสคริปต์เพื่อใช้ใน extendscript ของ adobe หรือโปรแกรมใดๆที่ใช้ ES3 เป็นพื้นฐานจะไม่สามารถใช้คำสั่งต่อไปนี้ได้

ES3 นั้นออกมาตั้งแต่ปี 1999 ซึ่งก็นานแล้ว หลังจากนั้นก็ไม่ได้มีความเปลี่ยนแปลงอะไรมากนัก จนมาถึง ES5 ในปี 2009 (ไม่มี ES4 จาก 3 โดดไป 5 เลย) ก็มีการเพิ่มความสามารถใหม่เข้ามาส่วนหนึ่ง แม้ว่าจะไม่ได้เยอะเท่ากับที่เพิ่มจาก ES5 ไปเป็นใน ES6 ตอนปี 2015

ความสามารถหลักๆที่เพิ่มเข้ามาได้แก่

- การจำกัดความเปลี่ยนแปลงของออบเจ็กต์ (บทนี้)
- การสร้างและกำหนดรายละเอียดพรอเพอร์ตีในออบเจ็กต์ (บทที่ ๒๖)
- เมธอด Object.getPrototypeOf สำหรับสำหรับหาโพรโทไทป์ของออบเจ็กต์ (บทที่ ๒๖)
- เมธอดต่างๆสำหรับไล่จัดการค่าในแถวลำดับ เช่น .map, .filter, .reduce, ฯลฯ (บทที่ ๒๗)
- มีออบเจ็กต์ JSON ซึ่งใช้การจัดการกับข้อมูล json (บทที่ ๒๘)
- การใช้ use strict เปิดโหมดเคร่งครัด (บทที่ ๒๙)
- เมธอด trim สำหรับตัดช่องว่างหัวท้ายสายอักขระ (บทที่ ๒๙)
- เมธอด indexOf กับ lastIndexOf สามารถใช้ในแถวลำดับได้ (บทที่ ๒๙)



การแช่แข็งออบเจ็กต์

ปกติออบเจ็กต์เมื่อสร้างขึ้นมาแล้วสามารถเปลี่ยนแปลงค่าพรอเพอร์ตีต่างๆได้อย่างอิสระ คือแก้ค่าพรอเพอร์ตีที่มีอยู่ได้ เพิ่มพรอเพอร์ตีใหม่ได้ หรือลบพรอเพอร์ตีที่มีอยู่ได้

แต่หากเราต้องการให้ออบเจ็กต์นั้นไม่สามารถทำการเปลี่ยนแปลงอะไรได้อีก ก็สามารถทำได้โดยการใช้ฟังก์ชันต่างๆซึ่งใช้จัดการสร้างข้อจำกัดความเปลี่ยนแปลงให้ออบเจ็กต์

คำสั่งต่างๆนั้นอยู่ในออบเจ็กต์ Object ได้แก่ Object.preventExtensions, Object.seal และ Object.freeze

อย่างแรกคือ Object.freeze ใช้เมื่อต้องการแช่ออบเจ็กต์ไว้ไม่ให้ทำการเปลี่ยนแปลงใดๆได้เลย

ออบเจ็กต์ที่ถูกแช่ไว้จะไม่สามารถแก้ค่าพรอเพอร์ตีได้ ไม่สามารถเพิ่มพรอเพอร์ตีใหม่ หรือลบพรอเพอร์ตีที่มีอยู่ได้
var katomnam = {
  khwamchu: 1500,
  unhaphum: 80
};
Object.freeze(katomnam);
katomnam.unhaphum = 100; // แก้ค่า (ไม่สำเร็จ)
alert(katomnam.unhaphum); // ได้ 80
delete katomnam.khwamchu; // ลบทิ้ง (ไม่สำเร็จ)
alert(katomnam.khwamchu); // ได้ 1500
katomnam.pH = 7; // เพิ่มพรอเพอร์ตีใหม่ (ไม่สำเร็จ)
alert(katomnam.pH); // ได้ undefined




การผนึกออบเจ็กต์

หากแค่ต้องการไม่ให้มีการใส่เพิ่มพรอเพอร์ตีใหม่หรือลบพรอเพอร์ตีที่มีอยู่เดิม แต่สามารถแก้ไขค่าในพรอเพอร์ตีที่มีอยู่ได้ อาจใช้ฟังก์ชัน Object.seal แทนที่จะใช้ Object.freeze
var katomnam = {
  khwamchu: 1500,
  unhaphum: 80
};
Object.seal(katomnam);
katomnam.unhaphum = 100; // แก้ค่า (สำเร็จ)
alert(katomnam.unhaphum); // ได้ 100
delete katomnam.khwamchu; // ลบทิ้ง (ไม่สำเร็จ)
alert(katomnam.khwamchu); // ได้ 1500
katomnam.pH = 7; // เพิ่มพรอเพอร์ตีใหม่ (ไม่สำเร็จ)
alert(katomnam.pH); // ได้ undefined



การทำให้ออบเจ็กต์เพิ่มพรอเพอร์ตีใหม่ไม่ได้

หากแค่ต้องการไม่ให้มีการใส่เพิ่มพรอเพอร์ตีใหม่ แต่สามารถแก้ไขค่าหรือลบพรอเพอร์ตีที่มีอยู่ได้ อาจใช้ฟังก์ชัน Object.preventExtensions
var katomnam = {
  khwamchu: 1500,
  unhaphum: 80
};
Object.preventExtensions(katomnam);
katomnam.unhaphum = 100; // แก้ค่า (สำเร็จ)
alert(katomnam.unhaphum); // ได้ 100
delete katomnam.khwamchu; // ลบทิ้ง (สำเร็จ)
alert(katomnam.khwamchu); // ได้ undefined
katomnam.pH = 7; // เพิ่มพรอเพอร์ตีใหม่ (ไม่สำเร็จ)
alert(katomnam.pH); // ได้ undefined



การตรวจสอบว่าออบเจ็กต์ถูกตั้งข้อจำกัดอะไรไว้บ้าง

การตรวจสอบว่าออบเจ็กต์ถูกจำกัดความเปลี่ยนแปลงไว้หรือไม่ ทำได้โดยใช้ฟังก์ชัน Object.isExtensible Object.isSealed Object.isFrozen

Object.isExtensible จะตรวจสอบว่าออบเจ็กต์สามารถขยายได้หรือไม่ ถ้ามีการใช้ Object.preventExtensions ไว้ก็จะขยายไม่ได้จึงได้ false

Object.isSealed จะตรวจสอบว่าถูกผนึกไว้หรือเปล่า ถ้าใช่ก็จะได้ true

Object.isFrozen จะตรวจสอบว่าถูกผนึกไว้หรือเปล่า ถ้าใช่ก็จะได้ true

ลองดูตัวอย่างทีละกรณี

กรณีที่ออบเจ็กต์โดน freeze ไว้
var obj = { a: 1 };
Object.freeze(obj);
alert(Object.isExtensible(obj)); // ได้ false
alert(Object.isSealed(obj)); // ได้ true
alert(Object.isFrozen(obj)); // ได้ true

กรณีที่แค่โดน seal
var obj = { b: 1 };
Object.seal(obj);
alert(Object.isExtensible(obj)); // ได้ false
alert(Object.isSealed(obj)); // ได้ true
alert(Object.isFrozen(obj)); // ได้ false

กรณีที่แค่ใช้ Object.preventExtensions
var obj = { c: 1 };
Object.preventExtensions(obj);
alert(Object.isExtensible(obj)); // ได้ false
alert(Object.isSealed(obj)); // ได้ false
alert(Object.isFrozen(obj)); // ได้ false

แต่หากออบเจ็กต์นั้นไม่มีพรอเพอร์ตีอยู่เลย แค่ใช้ Object.preventExtensions ก็เหมือนใช้ freeze แล้ว
var obj = {};
Object.preventExtensions(obj);
alert(Object.isExtensible(obj)); // ได้ false
alert(Object.isSealed(obj)); // ได้ true
alert(Object.isFrozen(obj)); // ได้ true



สรุปข้อจำกัดความเปลี่ยนแปลงของออบเจ็กต์

สรุปฟังก์ชันสำหรับจำกัดความเปลี่ยนแปลงทั้ง ๓ ตัวได้ดังนี้

  preventExtension seal freeze
เพิ่มพรอเพอร์ตี ไม่ได้ ไม่ได้ ไม่ได้
ลบพรอเพอร์ตี ได้ ไม่ได้ ไม่ได้
แก้ค่าพรอเพอร์ตี ได้ ได้ ไม่ได้



ข้อจำกัดไม่ได้รวมไปถึงออบเจ็กต์ด้านใน

จะเห็นว่าคำสั่งต่างๆที่กล่าวมาทำให้พรอเพอร์ตีในออบเจ็กต์ไม่มีการเปลี่ยนแปลงได้

อย่างไรก็ตาม หากพรอเพอร์ตีในออบเจ็กต์นั้นก็เป็นออบเจ็กต์ด้วย ตัวพรอเพอร์ตีที่เป็นออบเจ็กต์นั้นก็ยังทำการเปลี่ยนแปลงได้อยู่แม้ว่าออบเจ็กต์ตัวนอกจะถูกตั้งข้อจำกัดก็ตาม ไม่ได้รับผลไปด้วย

ตัวอย่างเช่น
var objNok = { objNai: {} };
Object.freeze(objNok);
objNok.objNai.prop = "xxx";
alert(objNok.objNai.prop); // ได้ xxx

ฉะนั้นแล้ว หากต้องการจะจำกัดการเปลี่ยนแปลงทั้งหมดก็ต้องใช้ Object.freeze กับออบเจ็กต์ด้านในไปด้วย
Object.freeze(objNok.objNai);
objNok.objNai.prop = "yyy";
alert(objNok.objNai.prop); // ได้ xxx

ดังนั้นจึงต้องระวังตรงนี้ด้วย เวลาที่ใช้กับออบเจ็กต์ที่พรอเพอร์ตีเป็นออบเจ็กต์




-----------------------------------------

囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧囧

ดูสถิติของหน้านี้

หมวดหมู่

-- คอมพิวเตอร์ >> เขียนโปรแกรม >> javascript

ไม่อนุญาตให้นำเนื้อหาของบทความไปลงที่อื่นโดยไม่ได้ขออนุญาตโดยเด็ดขาด หากต้องการนำบางส่วนไปลงสามารถทำได้โดยต้องไม่ใช่การก๊อปแปะแต่ให้เปลี่ยนคำพูดเป็นของตัวเอง หรือไม่ก็เขียนในลักษณะการยกข้อความอ้างอิง และไม่ว่ากรณีไหนก็ตาม ต้องให้เครดิตพร้อมใส่ลิงก์ของทุกบทความที่มีการใช้เนื้อหาเสมอ

สารบัญ

รวมคำแปลวลีเด็ดจากญี่ปุ่น
มอดูลต่างๆ
-- numpy
-- matplotlib

-- pandas
-- manim
-- opencv
-- pyqt
-- pytorch
การเรียนรู้ของเครื่อง
-- โครงข่าย
     ประสาทเทียม
ภาษา javascript
ภาษา mongol
ภาษาศาสตร์
maya
ความน่าจะเป็น
บันทึกในญี่ปุ่น
บันทึกในจีน
-- บันทึกในปักกิ่ง
-- บันทึกในฮ่องกง
-- บันทึกในมาเก๊า
บันทึกในไต้หวัน
บันทึกในยุโรปเหนือ
บันทึกในประเทศอื่นๆ
qiita
บทความอื่นๆ

บทความแบ่งตามหมวด



ติดตามอัปเดตของบล็อกได้ที่แฟนเพจ

  ค้นหาบทความ

  บทความแนะนำ

ตัวอักษรกรีกและเปรียบเทียบการใช้งานในภาษากรีกโบราณและกรีกสมัยใหม่
ที่มาของอักษรไทยและความเกี่ยวพันกับอักษรอื่นๆในตระกูลอักษรพราหมี
การสร้างแบบจำลองสามมิติเป็นไฟล์ .obj วิธีการอย่างง่ายที่ไม่ว่าใครก็ลองทำได้ทันที
รวมรายชื่อนักร้องเพลงกวางตุ้ง
ภาษาจีนแบ่งเป็นสำเนียงอะไรบ้าง มีความแตกต่างกันมากแค่ไหน
ทำความเข้าใจระบอบประชาธิปไตยจากประวัติศาสตร์ความเป็นมา
เรียนรู้วิธีการใช้ regular expression (regex)
การใช้ unix shell เบื้องต้น ใน linux และ mac
g ในภาษาญี่ปุ่นออกเสียง "ก" หรือ "ง" กันแน่
ทำความรู้จักกับปัญญาประดิษฐ์และการเรียนรู้ของเครื่อง
ค้นพบระบบดาวเคราะห์ ๘ ดวง เบื้องหลังความสำเร็จคือปัญญาประดิษฐ์ (AI)
หอดูดาวโบราณปักกิ่ง ตอนที่ ๑: แท่นสังเกตการณ์และสวนดอกไม้
พิพิธภัณฑ์สถาปัตยกรรมโบราณปักกิ่ง
เที่ยวเมืองตานตง ล่องเรือในน่านน้ำเกาหลีเหนือ
ตระเวนเที่ยวตามรอยฉากของอนิเมะในญี่ปุ่น
เที่ยวชมหอดูดาวที่ฐานสังเกตการณ์ซิงหลง
ทำไมจึงไม่ควรเขียนวรรณยุกต์เวลาทับศัพท์ภาษาต่างประเทศ

บทความแต่ละเดือน

2024年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2023年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2022年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2021年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

2020年

1月 2月 3月 4月
5月 6月 7月 8月
9月 10月 11月 12月

ค้นบทความเก่ากว่านั้น

ไทย

日本語

中文