0Pricing
JavaScript Academy · บทเรียน

การทำให้ออบเจ็กต์หยุดนิ่งแบบตื้นเทียบกับแบบลึก

ทำความเข้าใจว่าการหยุดนิ่งมีผลไปไกลเพียงใด

การทำให้ออบเจ็กต์หยุดนิ่งแบบตื้นเทียบกับแบบลึก เป็นบทเรียน JavaScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน JavaScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส JavaScript Academy มีบทเรียนทั้งหมด 4 บทเรียน

Freeze เป็นการจำกัดแบบตื้น

Object.freeze จำกัดเฉพาะ ระดับบนสุดของออบเจ็กต์ ออบเจ็กต์หรืออาร์เรย์ที่ซ้อนอยู่ซึ่งออบเจ็กต์นั้นอ้างอิงถึงยังเปลี่ยนแปลงได้อย่างสมบูรณ์

เรื่องนี้ทำให้นักพัฒนาหลายคนประหลาดใจและทำให้เกิดข้อผิดพลาดที่สังเกตได้ยาก

พิสูจน์ข้อจำกัดของการจำกัดแบบตื้น

ลอง freeze ออบเจ็กต์ที่มีออบเจ็กต์ซ้อนอยู่ ระดับบนสุดจะถูกจำกัด แต่คุณยังเปลี่ยนออบเจ็กต์ที่ซ้อนอยู่ได้

const user = Object.freeze({
  name: 'Ada',
  address: { city: 'London' }
});

user.name = 'Grace';
user.address.city = 'Paris';

console.log(user.name);
console.log(user.address.city);

อาร์เรย์ที่ซ้อนอยู่ก็เช่นกัน

อาร์เรย์ภายในออบเจ็กต์ที่ถูก freeze ก็ไม่ได้รับการป้องกันเช่นกัน คุณยังใช้ push เพิ่มสมาชิก นำสมาชิกออกจากท้ายอาร์เรย์ และกำหนดสมาชิกใหม่ได้

const state = Object.freeze({ tags: ['a', 'b'] });

state.tags.push('c');
state.tags[0] = 'X';

console.log(state.tags);

isFrozen ยืนยันผล

ออบเจ็กต์ที่ซ้อนอยู่รายงานค่า isFrozen เป็น false ซึ่งยืนยันว่าการ freeze ไม่ได้ครอบคลุมเข้าไปถึงภายใน

const obj = Object.freeze({ inner: { v: 1 } });

console.log(Object.isFrozen(obj));
console.log(Object.isFrozen(obj.inner));

เขียน deepFreeze

หากต้องการจำกัดทุกระดับ ให้เรียกตัวเองซ้ำดังนี้: freeze ออบเจ็กต์ก่อน แล้ว freeze พร็อพเพอร์ตีของออบเจ็กต์ที่ซ้อนอยู่แต่ละรายการ นี่คือ การ freeze แบบลึก

function deepFreeze(obj) {
  for (const key of Object.keys(obj)) {
    const value = obj[key];
    if (value && typeof value === 'object') {
      deepFreeze(value);
    }
  }
  return Object.freeze(obj);
}

const data = deepFreeze({ a: { b: { c: 1 } } });
data.a.b.c = 999;
console.log(data.a.b.c);

deepFreeze กับอาร์เรย์

อาร์เรย์ก็เป็นออบเจ็กต์เช่นกัน ดังนั้นการเรียกซ้ำแบบเดียวกันจึงสามารถ freeze อาร์เรย์ได้ด้วย การใช้ push และการเขียนสมาชิกจะถูกป้องกันในทุกระดับ

function deepFreeze(obj) {
  for (const key of Object.keys(obj)) {
    const value = obj[key];
    if (value && typeof value === 'object') deepFreeze(value);
  }
  return Object.freeze(obj);
}

const state = deepFreeze({ list: [1, 2, 3] });
state.list.push(4);
state.list[0] = 99;
console.log(state.list);

ตรวจสอบการ freeze แบบลึก

หลังจาก freeze แบบลึก ออบเจ็กต์ที่ซ้อนอยู่ทุกตัวจะรายงานค่า isFrozen เป็น true

function deepFreeze(obj) {
  for (const key of Object.keys(obj)) {
    const v = obj[key];
    if (v && typeof v === 'object') deepFreeze(v);
  }
  return Object.freeze(obj);
}

const o = deepFreeze({ a: { b: 1 } });
console.log(Object.isFrozen(o));
console.log(Object.isFrozen(o.a));

ป้องกันการอ้างอิงวนรอบ

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

function deepFreeze(obj) {
  if (Object.isFrozen(obj)) return obj;
  for (const key of Object.keys(obj)) {
    const v = obj[key];
    if (v && typeof v === 'object') deepFreeze(v);
  }
  return Object.freeze(obj);
}

const a = { name: 'a' };
a.self = a;
deepFreeze(a);
console.log(Object.isFrozen(a.self));

ต้นทุนของการ freeze แบบลึก

การ freeze แบบลึกจะเยี่ยมชมค่าที่ซ้อนอยู่ทุกค่า จึงใช้เวลาและหน่วยความจำมากสำหรับโครงสร้างขนาดใหญ่ ควร freeze เฉพาะสิ่งที่ต้องการป้องกันจริง ๆ เช่น config ที่ใช้ร่วมกันหรือค่าคงที่

function deepFreeze(obj) {
  if (Object.isFrozen(obj)) return obj;
  Object.keys(obj).forEach(k => {
    const v = obj[k];
    if (v && typeof v === 'object') deepFreeze(v);
  });
  return Object.freeze(obj);
}

const small = deepFreeze({ a: 1, b: { c: 2 } });
console.log('frozen deeply:', Object.isFrozen(small.b));

เมื่อการจำกัดแบบตื้นก็เพียงพอ

หากออบเจ็กต์เก็บเฉพาะค่าพื้นฐาน การใช้ Object.freeze แบบตื้นก็ป้องกันออบเจ็กต์ได้อย่างสมบูรณ์แล้ว การ freeze แบบลึกจะมีความสำคัญเฉพาะเมื่อมีออบเจ็กต์หรืออาร์เรย์ที่ซ้อนอยู่

const flat = Object.freeze({ a: 1, b: 'two', c: true });
flat.a = 100;
console.log(flat.a);
console.log(Object.isFrozen(flat));

เหตุใดจึงสำคัญ

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

const config = Object.freeze({ db: { host: 'local' } });
config.db.host = 'changed';
console.log('shallow freeze leaked:', config.db.host);

ตรวจสอบความเข้าใจอย่างรวดเร็ว

หลังจาก Object.freeze({ a: { b: 1 } }) คุณสามารถเปลี่ยนค่า b ที่ซ้อนอยู่ได้หรือไม่

ทบทวน: การ freeze แบบตื้นเทียบกับแบบลึก

คุณได้เรียนรู้ข้อจำกัดด้านระดับของการ freeze แล้ว

  • Object.freeze เป็นการจำกัดแบบ ตื้น ออบเจ็กต์และอาร์เรย์ที่ซ้อนอยู่จึงยังเปลี่ยนแปลงได้
  • deepFreeze เรียกซ้ำเพื่อจำกัดทุกระดับ
  • ป้องกันการอ้างอิงวนรอบด้วยการข้ามออบเจ็กต์ที่ถูก freeze แล้ว
  • การ freeze แบบลึกมีต้นทุน ดังนั้นควร freeze เฉพาะสิ่งที่ต้องการป้องกัน

คำถามที่พบบ่อย

บทเรียน “การทำให้ออบเจ็กต์หยุดนิ่งแบบตื้นเทียบกับแบบลึก” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “การทำให้ออบเจ็กต์หยุดนิ่งแบบตื้นเทียบกับแบบลึก” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส JavaScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส JavaScript Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “การทำให้ออบเจ็กต์หยุดนิ่งแบบตื้นเทียบกับแบบลึก”

ทำความเข้าใจว่าการหยุดนิ่งมีผลไปไกลเพียงใด คุณปฏิบัติ JavaScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน JavaScript Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน JavaScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “การทำให้ออบเจ็กต์หยุดนิ่งแบบตื้นเทียบกับแบบลึก” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน JavaScript Academy นี้ได้ไหม

ได้ บทเรียน JavaScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. Object.freeze และ seal
  2. การทำให้ออบเจ็กต์หยุดนิ่งแบบตื้นเทียบกับแบบลึก
  3. รูปแบบการอัปเดตแบบไม่เปลี่ยนแปลงข้อมูลเดิม
  4. structuredClone สำหรับสำเนาเชิงลึก
← กลับไปที่ JavaScript Academy