การลบคุณสมบัติของอ็อบเจ็กต์ในขณะที่ทำซ้ำมันปลอดภัยหรือไม่?


102

เมื่อทำซ้ำคุณสมบัติของออบเจ็กต์จะปลอดภัยหรือไม่ที่จะลบออกขณะอยู่ในลูป for-in

ตัวอย่างเช่น:

for (var key in obj) {
    if (!obj.hasOwnProperty(key)) continue;

    if (shouldDelete(obj[key])) {
        delete obj[key];
    }
}

ในภาษาอื่น ๆ อีกมากมายที่ทำซ้ำบนอาร์เรย์หรือพจนานุกรมและการลบภายในที่ไม่ปลอดภัย อยู่ใน JS ได้หรือไม่?

(ฉันใช้ Spidermonkey runtime ของ Mozilla)


ฉันได้เริ่มต้นโปรดปรานกับคำถามนี้เพราะผมคิดว่าคำตอบที่ปัจจุบันมีไม่เพียงพอและไม่ได้ตอบคำถามตามที่นำเสนอ โปรดระบุแหล่งที่มาที่เกี่ยวข้องด้วย (โดยหวังว่าจะมาจากข้อมูลจำเพาะ) และ "นิสัยใจคอ" ที่น่าทึ่งหากมี
user2864740

คำตอบ:


120

ECMAScript 5.1 มาตรฐานส่วน 12.6.4 (สำหรับในลูป) พูดว่า:

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

ดังนั้นฉันคิดว่ามันชัดเจนว่ารหัสของ OP นั้นถูกกฎหมายและจะทำงานได้ตามที่คาดไว้ นิสัยใจคอของเบราว์เซอร์มีผลต่อลำดับการวนซ้ำและคำสั่งลบโดยทั่วไป แต่ไม่ใช่ว่ารหัส OPs จะทำงานหรือไม่ โดยทั่วไปควรลบคุณสมบัติปัจจุบันในการวนซ้ำเท่านั้น - การลบคุณสมบัติอื่น ๆ ในออบเจ็กต์จะทำให้รวมคุณสมบัติเหล่านี้โดยไม่คาดคิด (หากเข้าชมแล้ว) หรือไม่รวมอยู่ในการทำซ้ำแม้ว่าจะเป็นเรื่องที่น่ากังวลหรือไม่ก็ตามขึ้นอยู่กับ สถานการณ์.

ดูสิ่งนี้ด้วย:

สิ่งเหล่านี้ไม่มีผลต่อรหัสของ OP จริงๆ


1
ฉันเพิ่งสังเกตว่าฉันใส่คำพูดมาตรฐานเดียวกันกับคำตอบอื่น ๆ ขอโทษ
TomW

17

จากข้อกำหนดJavascript / ECMAScript (เฉพาะ12.6.4 The for-in Statement ):

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.