การอ้างอิงที่รัดกุมใน JavaScript: การอ้างอิงของออบเจ็กต์คือการอ้างอิงที่รัดกุมใน JavaScript นั่นคือเมื่อ将一个引用对象通过变量或常量保存
ที่ ดังนั้นตัวแปรหรือค่าคงที่จะเป็นการอ้างอิงที่รัดกุม และวัตถุจะไม่ถูกรีไซเคิล
การอ้างอิงที่อ่อนแอใน JavaScript: WeakMaps และ WeakSets เป็นวิธีเดียวที่เราสามารถใช้การอ้างอิงที่อ่อนแอใน JavaScript将一个对象作为键添加
ใน WeakMap หรือ WeakSet ไม่ได้ป้องกันวัตถุเหล่านี้จากการรีไซเคิล
การอ้างอิงที่ชัดเจนคือเด็ก A อุ้มสุนัขและเชื่อมต่อกันด้วยโซ่สุนัข
การอ้างอิงที่อ่อนแอคือมีคน B ชี้ไปที่สุนัขที่ A จับอยู่และพูดว่า: เฮ้ มีสุนัขอยู่ที่นั่น และ B ชี้ไปที่สุนัข แต่ไม่มีอะไรผูกติดกันระหว่างพวกเขา
เมื่อ A ปล่อยสายจูงสุนัข สุนัขจะวิ่งหนี (ถูกเก็บขยะ) ไม่ว่า B จะยังคงชี้อยู่หรือไม่ก็ตาม
อย่างไรก็ตาม เมื่อ B ไม่ชี้ไปที่สุนัขอีกต่อไป สุนัขยังคงถูก A จับไว้ ซึ่งจะไม่ส่งผลกระทบต่อการวิ่งหนี
ให้ผู้คน = {name:'Zhang San',age:25} ให้ people1 = people;
ในโค้ดข้างต้น เมื่อเรากำหนด {name:'张三',age:25}
ให้กับตัวแปร people จะมีเส้นเชื่อมต่อพวกเขาในหน่วยความจำ:
จากนั้นสร้างตัวแปร people1 และกำหนดบุคคลให้กับ people1 ซึ่งเทียบเท่ากับ people1 ที่อ้างอิงอ็อบเจ็กต์นี้ด้วย:
มาดูกันว่าเกิดอะไรขึ้นเมื่อเราใช้ประเภท WeakSet และ WeakMap ที่เพิ่งเปิดตัวใน ES6 เพื่อจัดเก็บค่าอ้างอิง
ให้คน = {ชื่อ:'จางซาน' อายุ:25} ให้ people1 = คน; ให้ set = new WeakSet(); set.add(people);
เราได้สร้างอินสแตนซ์ WeakSet() ใหม่และเพิ่มบุคคลผ่านวิธีการ add ค่าอ้างอิงที่สอดคล้องกับบุคคลคือ {name:'张三',age:25}
จะเห็นได้ว่าค่า {name:'张三',age:25}
ในอินสแตนซ์ที่ตั้งค่าอ้างถึง {name:'张三',age:25}
(ในหน่วยความจำจริง จะชี้ไปที่สแต็กของข้อมูล การอ้างอิงตัวชี้ สแต็กจะชี้ไปที่ค่าของที่อยู่ที่สอดคล้องกันในฮีปที่เกี่ยวข้อง) และสิ่งสำคัญคือต้องทราบว่า "บรรทัด" ของการอ้างอิงที่อ่อนแอนี้มีความโปร่งใส สิ่งนี้หมายความว่าอย่างไร อะไรคือความแตกต่างระหว่างมันกับใบเสนอราคาที่แข็งแกร่ง?
สรุปหนึ่งประโยค: การอ้างอิงที่ชัดเจนถือเป็น "ความเชื่อมโยง" โดยการอ้างอิง {name:'张三',age:25}
ในขณะที่การอ้างอิงที่ไม่ชัดเจนไม่ได้รับการยอมรับ นั่นคือการอ้างอิงไม่ทราบว่ามีการอ้างอิงโดยอินสแตนซ์ที่ตั้งค่าไว้
ซึ่งหมายความว่าการรวบรวมขยะไม่ทราบว่าการอ้างอิงนั้นอ้างอิงโดยอินสแตนซ์ที่ตั้งค่าไว้ จากนั้น หากการเชื่อมต่อการอ้างอิงที่รัดกุมทั้งหมดของการอ้างอิงถูกตัดการเชื่อมต่อ (ตัวแปรถูกกำหนดให้เป็นโมฆะหรือสถานการณ์อื่นๆ) การอ้างอิงจะถูกทำลายแบบขยะ แม้ว่าอินสแตนซ์ที่ตั้งค่าไว้จะยังคงอ้างอิงถึงการอ้างอิงก็ตาม
ให้คน = {ชื่อ:'จางซาน' อายุ:25} ให้ people1 = คน; ให้ set = new WeakSet(); set.add(คน); คน = โมฆะ; people1 = null;
จะเกิดอะไรขึ้นถ้าเราตัดการเชื่อมต่อการอ้างอิงที่รัดกุมทั้งหมด?
เนื่องจากการอ้างอิงที่รัดกุมทั้งหมดถูกตัดการเชื่อมต่อ การรวบรวมขยะจึงพิจารณาว่าการอ้างอิง {name:'张三',age:25}
ไม่จำเป็นอีกต่อไป และจะทำลายมัน จากนั้นการอ้างอิงที่ใช้โดยอินสแตนซ์ชุดที่เกี่ยวข้องจะไม่มีอยู่อีกต่อไป แม้ว่าอินสแตนซ์ชุดจะยังคงใช้การอ้างอิงอยู่ก็ตาม
1. การอ้างอิงไปยังวัตถุใน WeakSet คือการอ้างอิงที่อ่อนแอ กล่าวคือ แม้ว่าชุดที่อ่อนแอจะ "อ้างอิง" วัตถุ แต่การรวบรวมขยะก็ไม่นับการอ้างอิงนี้เป็น "การอ้างอิง" เป็น ตราบใดที่ไม่มีการอ้างอิงที่ชัดเจนในที่อื่น วัตถุนี้ไม่สามารถเข้าถึงได้และอาจสามารถนำกลับมาใช้ใหม่ได้ตลอดเวลา สามารถจัดเก็บได้เฉพาะประเภทการอ้างอิงและไม่สามารถระบุหรือเคลียร์ได้
2. WeakMap คล้ายกับ Map แต่ไม่สามารถนับได้ ไม่สามารถล้างได้ และวัตถุที่อ้างอิงด้วยคีย์ถือเป็นการอ้างอิงที่อ่อนแอ
3. WeakSet เหมาะสำหรับการจัดเก็บกลุ่มของวัตถุชั่วคราวและจัดเก็บข้อมูลที่เชื่อมโยงกับวัตถุ ตราบใดที่วัตถุเหล่านี้หายไปจากภายนอก การอ้างอิงใน WeakSet จะหายไปโดยอัตโนมัติ เนื่องจากคุณสมบัติข้างต้น สมาชิกของ WeakSet จึงไม่เหมาะสำหรับการอ้างอิงเนื่องจากจะหายไปเมื่อใดก็ได้
4. การอ้างอิงที่ชัดเจนบางครั้งลืมที่จะอ้างอิง ทำให้ไม่สามารถปล่อยหน่วยความจำได้ ซึ่งอาจทำให้หน่วยความจำรั่ว การอ้างอิงที่อ่อนแอจะไม่รวมอยู่ในกลไกการรวบรวมขยะ ดังนั้นจึงไม่มีปัญหานี้