เหตุใดการขยายต้นแบบ DOM / วัตถุในตัวจึงเป็นความคิดที่ไม่ดี


15

ฉันกำลังมองหาคำตอบที่ชัดเจนว่าทำไมการขยายต้นแบบในตัวจึงถูกลงโทษอย่างหนักในชุมชนนักพัฒนา JS ฉันได้รับการใช้กรอบต้นแบบ JS ในขณะที่และให้ฉันทำดูเหมือนมากขึ้นสง่างามกว่า[1,2,3].each(doStuff) $.each([1,2,3], doStuff)ฉันรู้ว่ามันสร้าง "มลภาวะเนมสเปซ" แต่ฉันไม่เข้าใจว่าทำไมจึงถือว่าเป็นสิ่งที่ไม่ดี นอกจากนี้ยังมีการลดลงของประสิทธิภาพที่แท้จริงที่เกี่ยวข้องกับการขยายต้นแบบในตัว? ขอบคุณ!


1
สิ่งหนึ่งคือfor(var ... in ...)ลูปจะเกิดความสับสนเนื่องจากฟังก์ชั่นต้นแบบถูกส่งผ่านเช่นกัน
pimvdb

4
"ตีสอนอย่างหนัก" จริงเหรอ! พระเจ้าที่ดีผู้ชาย:] ​​คุณโอเคไหม
pixelbobby

คำตอบ:


12

ฉันขอแนะนำให้คุณอ่านบทความนี้ซึ่งฉันคิดว่าอธิบายได้ค่อนข้างดีว่าทำไมการขยายวัตถุเป็นความคิดที่ไม่ดีสำหรับ Prototype เช่นกัน

สรุป:

ขาดสเปค

การเปิดรับ "วัตถุต้นแบบ" ไม่ได้เป็นส่วนหนึ่งของข้อมูลจำเพาะใด ๆ [... ] เพื่อให้การใช้งานสอดคล้องกับ DOM ระดับ 2 อย่างสมบูรณ์ไม่จำเป็นต้องเปิดเผยโหนดโกลบอล, องค์ประกอบ, HTMLElement ฯลฯ เหล่านั้น

โฮสต์วัตถุไม่มีกฎ

วัตถุ DOM เป็นวัตถุโฮสต์ [... ] วัตถุโฮสต์อาจใช้วิธีการภายในเหล่านี้กับพฤติกรรมใด ๆ ที่ขึ้นอยู่กับการใช้งานหรืออาจเป็นไปได้ว่าวัตถุโฮสต์ใช้วิธีการภายในบางวิธีเท่านั้นและไม่ใช่วิธีอื่น

[... ] พฤติกรรมวิธีการภายในขึ้นอยู่กับการนำไปใช้งาน [... ] ตามคำนิยามคุณกำลังทำงานกับสิ่งที่ได้รับอนุญาตให้ทำงานในลักษณะที่คาดเดาไม่ได้และเอาแน่เอานอนไม่ได้

โอกาสเกิดการชน

ด้วยสภาพแวดล้อมที่มีการใช้งานจำนวนมากในปัจจุบันมันเป็นไปไม่ได้ที่จะบอกได้ว่าคุณสมบัติบางอย่างนั้นไม่ได้เป็นส่วนหนึ่งของ DOM [ ... ]

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

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

ประสิทธิภาพค่าใช้จ่าย

[... ] เบราว์เซอร์ที่ไม่รองรับส่วนขยายองค์ประกอบเช่น IE 6, 7, Safari 2.x เป็นต้นต้องใช้ส่วนขยายวัตถุด้วยตนเอง ปัญหาคือการขยายด้วยตนเองช้าไม่สะดวกและไม่ขยาย

[... ] เมื่อคุณเริ่มขยายองค์ประกอบไลบรารี API ส่วนใหญ่ต้องการกลับองค์ประกอบเพิ่มเติมทุกที่ ดังนั้นวิธีการสืบค้นเช่น $$ อาจสิ้นสุดการขยายองค์ประกอบทุกรายการในแบบสอบถาม

IE DOM เป็นระเบียบ

ดังที่แสดงในส่วนก่อนหน้าส่วนขยาย DOM แบบแมนนวลนั้นไม่เป็นระเบียบ แต่การขยาย DOM แบบแมนนวลใน IE นั้นยิ่งแย่ [... ]

โบนัส: ข้อบกพร่องของเบราว์เซอร์


9

อีกเหตุผลหนึ่งคือการอ่าน / บำรุงรักษารหัส หากผู้พัฒนารายอื่น (โดยเฉพาะมือใหม่) อ่านรหัสของฉันและเห็น[0, 1, 2].foo(...)พวกเขาอาจไม่ทราบว่าวิธีการ foo นั้นคืออะไรหรือจะหาเอกสาร / แหล่งที่มาได้จากที่ใด foo เป็นส่วนขยายของภาษาที่เพิ่มขึ้นโดย prototype.js หรือโดยไลบรารีอื่นที่ใช้งานอยู่หรือโดยส่วนอื่น ๆ ของรหัสของฉันในไฟล์อื่นหรือเป็นวิธี JavaScript ดั้งเดิมที่พวกเขาไม่รู้ พวกเขาต้องตามล่าหามันและอาจไม่พบมันทันที (หรือหากมีข้อขัดแย้งพวกเขาอาจไม่พบสิ่งที่ถูกต้อง)

ด้วยวิธี jQuery ถ้าคุณเห็น$.foo(...)namespace ของเมธอด foo จะทำให้เห็นได้อย่างชัดเจนว่าจะหาคำนิยาม / เอกสารของมันได้ที่ใดถ้าคุณไม่รู้ว่ามันทำอะไร


การค้นพบวิธีการที่มาจากเป็นสิ่งสำคัญมากสำหรับผู้อ่าน แม้ว่าฉันจะไม่คิดว่า jQuery เป็นตัวอย่างที่ดีเนื่องจากเครื่องหมายดอลลาร์เป็นสิ่งที่ท้าทายเมื่อคุณข้ามไปอ่านโค้ดเว็บและไม่รู้ว่ามันคืออะไร
Simon Feltman

4

นี่คือปัญหาพื้นฐาน: จะเกิดอะไรขึ้นถ้าคุณมีเครื่องมือสองอย่างที่ขยายต้นแบบในวิธีที่ไม่เข้ากันหรือขยายวิธีที่เรียกกันโดยทั่วไปในวิธีที่พวกเขาให้ผลลัพธ์ที่แตกต่างกัน (นี่เป็นปัญหาเฉพาะสำหรับfor...inJavaScript) ในพฤติกรรมปกติของพวกเขาที่จะทำลาย?

โดยทั่วไปมันเป็นปัญหาเดียวกับที่คุณมีเมื่อคุณใช้ตัวแปรโกลบอลในทางที่ผิด ด้วยตัวเองอาจจะไม่มีอะไรเลวร้ายเกิดขึ้น แต่มันจะเปิดคุณขึ้นสำหรับปัญหาเมื่อโค้ดสองชิ้นแยกกันอย่างกระทันหันก็ก้าวเข้าหากัน (และมันเป็นความเจ็บปวดที่จะดีบั๊กเมื่อเกิดขึ้น)

prototype.js แน่นอนเป็นที่รู้จักกันดีและเครื่องมือส่วนใหญ่แก้ไขสิ่งที่มันทำ ในทำนองเดียวกันฉันแน่ใจว่ามีหลายกรณีที่การขยายต้นแบบพื้นฐานเป็นสิ่งที่ถูกต้อง แต่มันเป็นสิ่งที่ต้องทำด้วยความระมัดระวัง


1

ไม่แน่ใจว่านี่ยังคงเป็นปัญหาอีกต่อไป แต่ประสบการณ์ของฉันกับ Internet Explorer รุ่นก่อนหน้านี้คือบางครั้งมันเป็นไปไม่ได้ที่จะขยายประเภท build-in บางประเภท


1

มีสองประเด็นแยกกันที่นี่ สิ่งแรกคือต้นแบบทั่วไปที่มีอยู่แล้วภายในและต้นแบบอื่น ๆ นั้นขยายต้นแบบ DOM โดยเฉพาะ ข้อโต้แย้งต่อต้านการขยายต้นแบบในตัว:

  • ศักยภาพการปะทะกัน: โค้ดสองส่วนจากแหล่งต่าง ๆ ทั้งสองกำหนดคุณสมบัติเดียวกันในต้นแบบเดียวกัน
  • ผลข้างเคียง: การขยายArray.prototypeหรือObject.prototypeอาจมีผลต่อการเคาะเช่นการเพิ่มวิธีการขยายที่ระบุในfor...inลูป

สำหรับการขยายต้นแบบ DOM นั้นยังคงมีข้อโต้แย้งที่อาจเกิดขึ้นข้างต้น นอกจากนี้โหนด DOM เป็นวัตถุโฮสต์และไม่อยู่ภายใต้กฎปกติใด ๆ ของวัตถุ JavaScript ดั้งเดิม พวกเขาสามารถทำสิ่งที่พวกเขาชอบและไม่มีภาระผูกพันในการจัดหาวัตถุต้นแบบที่สมเหตุสมผลหรือแม้แต่อนุญาตคุณสมบัติพิเศษ ("expando") IE ในการออกกำลังกายโดยเฉพาะอย่างยิ่งสิทธินี้ให้ไม่มีต้นแบบสำหรับ DOM วัตถุก่อน IE 9 และมี weirdnesses ต่างๆเกี่ยวกับคุณสมบัติในวัตถุ DOM ต่างๆ (แม้ว่าคุณคุณสมบัติทั่วไปมอบหมายตกลงกับองค์ประกอบให้ชุดไม่มีอะไรdocument.expandoที่จะfalse.)

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