แนวทางปฏิบัติที่ดีที่สุดของ JavaScript ขยาย Natives ด้วย *statics*

บางคนจะบอกคุณว่าการเพิ่ม ต้นแบบ ให้กับ JavaScript Native เป็นสิ่งที่ชั่วร้าย ตัวอย่างเช่น:

String.prototype.format = function(format, replacements) {
    ...
};

ตอนนี้สำหรับผู้ที่เห็นด้วยกับสิ่งนั้น (ถ้าคุณไม่ทำ ไม่ต้องตอบกลับด้วยคำตอบ ความคิดเห็นของคุณคือ N/A นี่ไม่ใช่การสนทนาเกี่ยวกับต้นแบบ) กำลังเพิ่มวิธี static ให้กับชาวพื้นเมืองอย่างเท่าเทียมกัน ความชั่วร้าย? (จนบัดนี้และต่อจากนี้ไป "คงที่" หมายถึงเพียงวิธีการที่บริบทไม่ใช่อินสแตนซ์)

ตัวอย่างเช่น เมื่อพิจารณาว่าการสร้าง String.prototype.format นั้นชั่วร้าย การเพิ่มมันเป็น static ถือเป็นแนวทางปฏิบัติที่ยอมรับได้หรือไม่

String.format = function(format, replacements) {
    ...
};

การขยายเนทีฟด้วยวิธีคงที่มีความแตกต่างอย่างไรเกี่ยวกับแนวทางปฏิบัติที่ดีที่สุดมากกว่าการขยายเนทีฟด้วยต้นแบบ ไม่ว่าคุณจะต่อต้านการขยาย Native แต่อย่างใด หรือคุณไม่มีใครในค่ายที่ยอมรับส่วนขยาย static ในขณะที่ prototypal ไม่เป็นที่ยอมรับ


person user979672    schedule 26.10.2011    source แหล่งที่มา
comment
สาเหตุหลักประการหนึ่งก็เหมือนกับการขยายต้นแบบ: คุณขยายอ็อบเจ็กต์ของผู้อื่น ในโครงการขนาดใหญ่ที่ดำเนินมายาวนานซึ่งมีผู้คนจำนวนมาก (เปลี่ยนแปลงตลอดเวลา) โดยทั่วไปแล้วคุณต้องการหลีกเลี่ยงสิ่งนั้น และใช้อินเทอร์เฟซที่กำหนดไว้อย่างชัดเจนระหว่างโค้ดของบุคคล (หรือของทีม) ที่แตกต่างกัน เพราะถ้าคุณไม่ทำ คุณจะไปอยู่ในไฟชำระ หากไม่อยู่ในนรกโดยตรง :) เหตุผลอื่นๆ ทั้งหมดที่ผู้คนมักจะให้ เช่น อาจมีฟังก์ชันที่มีชื่อนั้นในอนาคต ก็มีจริง แต่เมื่อเปรียบเทียบกับ ข้างต้นเล็กน้อย - คุณจะพบว่าคุณเคยทำงานในโครงการขนาดใหญ่เช่นนี้หรือไม่ ดังนั้น...   -  person Mörre    schedule 26.10.2011
comment
...ในขณะที่มีคำตอบด้านเทคนิคอยู่หลายข้อ แต่คำตอบที่สำคัญที่สุด (จากมุมมองของอุตสาหกรรม โปรแกรมเมอร์ jQuery ในโครงการขนาดเล็กแต่ละคนจะไม่สนใจมากนัก) คือหนึ่งในบุคลากรและฝ่ายบริหาร หากคุณไม่สนใจแง่มุมนั้น คุณก็เปิดรับคำตอบที่ถูกต้องที่หลากหลายมากขึ้น   -  person Mörre    schedule 26.10.2011


คำตอบ (2)


ถามตัวเองว่าทำไมการขยายชนพื้นเมืองจึงชั่วร้าย

สาเหตุทั่วไปคือ

  • ไม่รองรับอนาคต จะเป็นอย่างไรหากมาตรฐานบอกว่า "จะต้องมี String.format"
  • ไม่ผ่านการพิสูจน์ในอดีต การเพิ่มคุณสมบัตินับไม่ถ้วนให้กับต้นแบบจะทำให้โค้ดเสียหาย
  • อาจทำให้เกิดความสับสนว่าอะไรเป็นเรื่องธรรมดาและอะไรเป็นมาตรฐาน
  • อาจทำลายโค้ดที่ไม่ถูกต้อง (พิมพ์เป็ด, ดูเหมือนเป็ด, quaks เหมือน --- โยนข้อยกเว้น :()

มันเป็นเรื่องของการชั่งน้ำหนักว่าคุณเห็นคุณค่าของเหตุผลเหล่านั้นมากแค่ไหน ฉันสนใจแค่ #1 เท่านั้น (การพิสูจน์อนาคต)

person Raynos    schedule 26.10.2011

การเพิ่มวิธีการคงที่ให้กับ Constructor ดั้งเดิมไม่น่าจะมีผลกระทบที่ไม่คาดคิดกับโค้ดของผู้อื่นหรือเวลาที่ใช้ในการสร้างวัตถุโดยใช้ Constructor ดังกล่าว

อย่างไรก็ตาม เมื่อคุณเพิ่มวิธีการต้นแบบให้กับ Constrcutor ดั้งเดิม ทุกอินสแตนซ์ (แม้แต่อินสแตนซ์ที่สร้างขึ้นเพื่อดำเนินการเช่น "test".indexOf("t") จะมีค่าใช้จ่ายเพิ่มเติมสำหรับวิธีการของคุณ การวนซ้ำคุณสมบัติของวัตถุหรือความสามารถในการทดสอบ (เนื่องจากเรามักจะไม่สามารถตัดสินวัตถุตามประเภทของมันได้) จะยากขึ้น

สมมติว่าคุณเพิ่ม String.prototype.forEach ในโค้ดของคุณ ที่จะรั่วไหลเข้าไปในทุกโมดูล ตอนนี้เมื่อมีโค้ดอื่นทดสอบสำหรับเมธอด forEach (คิดว่าเป็นอาร์เรย์ในเบราว์เซอร์สมัยใหม่) พวกเขาจะได้รับสตริงแทน - ชั่วร้าย

person AutoSponge    schedule 26.10.2011
comment
ทำไมถึงขึ้น 2 แต้ม? มีการระบุอย่างชัดเจนว่าปัญหาต้นแบบเป็นที่รู้จักแล้ว! - person Mörre; 26.10.2011