φυβλαςのβλογ
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
モンゴル語
言語学
maya
確率論
日本での日記
中国での日記
-- 北京での日記
-- 香港での日記
-- 澳門での日記
台灣での日記
北欧での日記
他の国での日記
qiita
その他の記事

記事の類別



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

  記事を検索

  おすすめの記事

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

ไทย

日本語

中文