คุณจะใช้การพิมพ์เป็ดในจาวาสคริปต์โดยไม่ตรวจสอบคุณสมบัติและวิธีการได้อย่างไร


11

ฉันรู้ว่าจาวาสคริปต์ใช้การพิมพ์เป็ดและตอนแรกฉันคิดว่านี่จะทำให้ความแตกต่างง่ายเมื่อเทียบกับภาษาที่พิมพ์อย่างยิ่งเช่น C # แต่ตอนนี้ฟังก์ชั่นของฉันที่รับการโต้แย้งจะเกลื่อนไปด้วยสิ่งต่าง ๆ เช่น:

if(myObj.hasSomeProperty())

หรือ

if(myObj.hasSomeMethod())

หรือ

if(isNumber(myParam))

เป็นต้น

นี่มันน่าเกลียดสำหรับฉันจริงๆ ฉันมาจากพื้นหลัง C # และฉันพบว่าอินเตอร์เฟสที่กำหนดไว้นั้นดีกว่ามาก

ฉันสงสัยว่าฉันพยายามใช้กลยุทธ์ที่มีประสิทธิภาพในภาษาที่พิมพ์แบบคงที่หรือไม่และมีวิธีที่ดีกว่าในการทำเช่นนี้ใน javascript หรือไม่

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


2
ฉันคิดว่าคุณอาจจะคลำหาลักษณะของภาษาที่พิมพ์แบบไดนามิก คุณต้องคุ้นเคยกับความคิดที่ว่าข้อผิดพลาดจำนวนมากจะเกิดขึ้นที่รันไทม์แทนที่จะรวบรวมเวลา หากคุณรู้สึกว่าจำเป็นต้องตรวจสอบว่าทุกข้อโต้แย้งเป็นตัวเลขในทุกฟังก์ชั่นที่ป้อนตัวเลขมันอาจกลายเป็นภาระค่อนข้างมาก สำหรับขนาดใด ๆ ฉันพบว่ามันเป็นสิ่งสำคัญที่จะช่วยให้ฟังก์ชั่นล้มเหลวหากมีการพิมพ์ผิดประเภท แต่การมุ่งเน้นที่มีประสิทธิผลมากขึ้นอาจจะเป็นการสร้างแบบทดสอบ

ที่ซึ่งอาจช่วยทำการตรวจสอบเหล่านี้เพื่อให้แน่ใจว่าประเภทเป็นไปตามข้อกำหนดของอินเทอร์เฟซที่จำเป็น (การตรวจสอบเพื่อดูว่าพวกเขามีวิธีการที่จำเป็นหรือไม่) อยู่ในฟังก์ชันส่วนกลางและใช้กันอย่างแพร่หลาย ตัวชี้วัดการมีเพศสัมพันธ์ / afferent มาร์ตินให้) นั่นควรเป็นเป้าหมายที่ค่อนข้างเล็ก โดยทั่วไปมักจะมีฟังก์ชั่นในการใช้งานครั้งเดียวมากมายซึ่งแยกได้ในขอบเขตซึ่งอาจไม่จำเป็นต้องมีชุดการตรวจสอบรันไทม์ที่ครอบคลุม พวกเขาไม่ได้สะสมความซับซ้อนมากนัก

สลับเป็น Type Script มันยังคงพิมพ์เป็ด แต่รองรับการพิมพ์คงที่เพื่อตรวจสอบข้อผิดพลาดจำนวนมากในเวลารวบรวม
CodesInChaos

2
คุณได้ตีปัญหาที่ใหญ่ที่สุดเพียงอย่างเดียวของการพิมพ์เป็ด: พลังนั้นมาจากความอ่อนแอ หากคุณต้องการทำจาวาสคริปต์เชิงวัตถุคุณต้องอยู่กับข้อผิดพลาดขณะทำงานและหวังว่าการทดสอบหน่วยของคุณจะพบพวกเขาในไม่ช้าหลังจากที่คุณสร้างพวกเขา :-(
Ross Patterson

@RossPatterson ปัญหา OPs เกิดจากการพิมพ์แบบไดนามิกไม่ใช่การพิมพ์แบบเป็ด TypeScript และ Go เป็นทั้งเป็ดพิมพ์ แต่ยังหลีกเลี่ยงปัญหาของ OP ปัญหาเกี่ยวกับการพิมพ์เป็ดคือปัญหาที่แตกต่างกันคือคุณสามารถมีสมาชิกที่ผ่านการทดสอบเป็ดได้ แต่อย่าทำตามสัญญาที่คุณคาดไว้
CodesInChaos

คำตอบ:


11

คุณจะใช้การพิมพ์เป็ดในจาวาสคริปต์โดยไม่ตรวจสอบคุณสมบัติและวิธีการได้อย่างไร

ง่าย: ไม่ต้องตรวจสอบคุณสมบัติและวิธีการเสมอไป

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

ฉันรู้ว่าจาวาสคริปต์ใช้การพิมพ์เป็ดและตอนแรกฉันคิดว่านี่จะทำให้ความแตกต่างง่ายเมื่อเทียบกับภาษาที่พิมพ์อย่างยิ่งเช่น C #

คุณกำลังสับสนในการพิมพ์หลายแกนในแนวตั้ง มีการพิมพ์สี่แกนตั้งฉาก:

  • เมื่อ : การพิมพ์แบบไดนามิก (ไม่รู้จักและตรวจสอบประเภทจนกว่าจะถึงรันไทม์) กับการพิมพ์แบบคงที่ (รู้จักและตรวจสอบประเภทก่อนรันไทม์)
  • อะไร : การพิมพ์เป็ด (ประเภทจะขึ้นอยู่กับพฤติกรรม ), การพิมพ์โครงสร้าง (ประเภทจะขึ้นอยู่กับโครงสร้าง ) และการพิมพ์เล็กน้อย (ประเภทจะขึ้นอยู่กับชื่อ )
  • เห็นไหม การพิมพ์ที่ชัดเจน (ประเภทจะต้องมีคำอธิบายประกอบอย่างชัดเจน) กับการพิมพ์โดยนัย (ประเภทจะอนุมาน)
  • การพิมพ์ที่รัดกุมและการพิมพ์ที่ไม่รัดกุม - คุณอาจสังเกตเห็นว่าฉันไม่ได้ให้ชื่อลวงหรือคำอธิบายในวงเล็บเพราะนี่ไม่เหมือนคำศัพท์ทั้งเจ็ดด้านบน มีคำนิยามที่คลุมเครือประมาณครึ่งโหลซึ่งขัดแย้งกัน เป็นการดีที่คุณควรหลีกเลี่ยงข้อกำหนดเหล่านี้โดยสิ้นเชิงและหากคุณต้องใช้ให้กำหนดอย่างแม่นยำก่อน

เนื่องจากคุณกล่าวถึง C #: ส่วนใหญ่จะเป็นแบบสแตติก แต่สนับสนุนการพิมพ์แบบไดนามิกผ่านประเภทdynamicส่วนใหญ่จะถูกพิมพ์ชื่อ แต่ประเภทที่ไม่ระบุชื่อใช้การพิมพ์โครงสร้างและรูปแบบประโยค - พิมพ์หรือพิมพ์โครงสร้างส่วนใหญ่จะพิมพ์อย่างชัดเจน แต่สนับสนุนการพิมพ์โดยนัยสำหรับอาร์กิวเมนต์ประเภททั่วไปและตัวแปรท้องถิ่น (แม้ว่ากรณีตัวแปรท้องถิ่นค่อนข้างแปลกเมื่อเทียบกับภาษาอื่น ๆ ส่วนใหญ่เพราะคุณไม่สามารถออกจากประเภทแทนคุณต้อง ให้มันหลอกประเภทที่ชัดเจนvarกล่าวอีกนัยหนึ่งถ้าคุณต้องการประเภทที่แน่นอนคุณต้องพูดอย่างนั้น) ไม่ว่า C # นั้นจะพิมพ์อย่างรุนแรงหรือไม่ก็ตามเป็นคำนิยามของคำสองคำที่คุณใช้อย่างไรก็ตามโปรดทราบว่าอาจมีข้อผิดพลาดประเภท runtime มากมายใน C # โดยเฉพาะอย่างยิ่งเนื่องจากความแปรปรวนของอาร์เรย์ที่ไม่ปลอดภัย

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

การดีบักไม่ใช่ทักษะที่ง่ายต่อการเรียนรู้ อย่างไรก็ตามมีเทคนิคในการทำให้การดีบักง่ายขึ้นเช่นSaff Squeezeเป็นเทคนิคที่อธิบายโดย Kent Beck ซึ่งใช้การทดสอบและการปรับโครงสร้างใหม่สำหรับการดีบัก:

Hit 'em High, Hit' em Low :

การทดสอบการถดถอยและ Saff Squeeze

Kent Beck สถาบันทรีริเวอร์ส

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


ลิงก์ยอดนิยมที่มีค่าสูงจะได้รับ http 500 สำหรับฉันโดยมี "หน้าไม่มีให้บริการอีกต่อไป" เป็นข้อความที่เน้นมนุษย์
joshp

ดูเหมือนว่าโดเมน threeriversinstitute.org จะถูกยกเลิก
Bart van Ingen Schenau

อ่า และจะไม่เก็บไว้แม้ในเครื่อง Wayback
Jörg W Mittag

ผู้โทรควรให้เกียรติสัญญาของพวกเขาอย่างไร ดูเหมือนว่าไม่มีวิธีในการสื่อสาร (ในโค้ด) ว่าพารามิเตอร์ควรเป็นอย่างไร ทุกฟังก์ชั่นเป็นของฟังก์ชั่นรูปแบบ fname (objParam, objParam, ... ) นี่หมายความว่าภาษาอย่างจาวาสคริปต์นั้นใช้เอกสารภายนอกทั้งหมดเพื่อสื่อสารการใช้งานหรือไม่?
กองพัน

@Legion: เอกสาร, การตั้งชื่อที่ดี, สามัญสำนึก, การทดสอบตามข้อกำหนดพฤติกรรม, อ่านรหัสต้นฉบับ, คุณตั้งชื่อมัน โปรดทราบว่าจริง ๆ แล้วไม่แตกต่างจากระบบประเภทที่อ่อนแอกว่าเช่น C # หรือ Java: เช่นความหมายของค่าส่งคืนIComparer<T>.Compare(T, T)จะชัดเจนจากเอกสารเท่านั้นไม่ใช่ประเภท และในรูปแบบของjava.util.Collections.binarySearch(java.util.List<T>)มันบอกว่า ...
Jörg W Mittag

1

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

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

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

เมื่อฉันได้รับข้อผิดพลาด runtime ฉันอย่างน้อยก็มี stack trace และในกรณีที่เกิดข้อผิดพลาดในเบราว์เซอร์ฉันมีความสามารถในการไปที่ระดับใด ๆ ของ stack trace และตรวจสอบตัวแปร โดยทั่วไปแล้วจะง่ายต่อการย้อนกลับไปที่ค่าที่ไม่ดีมาจากนั้นจึงติดตามกลับไปที่ปัญหาดั้งเดิม

หากคุณเป็นเหมือนฉันเมื่อฉันเขียนเป็นภาษาที่พิมพ์แบบสแตติกฉันจะเขียนบล็อคของโค้ดขนาดใหญ่กว่าก่อนการทดสอบและฉันไม่ได้ฝึกฝนในการติดตามค่าที่มาจากมัน การเขียนโปรแกรมในภาษาเช่นจาวาสคริปต์นั้นแตกต่างกันคุณต้องใช้ทักษะที่แตกต่างกัน ฉันสงสัยว่าการเขียนโปรแกรมแบบนี้ดูเหมือนจะยากขึ้นเพราะนั่นไม่ใช่ทักษะที่คุณพัฒนาขึ้นในการทำงานในภาษาอื่นเช่น C #

ต้องบอกว่าฉันคิดว่ามีหลายสิ่งที่ต้องพูดสำหรับประเภทที่ชัดเจน มันยอดเยี่ยมสำหรับเอกสารและการจับข้อผิดพลาดก่อน ฉันคิดว่าในอนาคตเราจะเห็นการยอมรับสิ่งต่าง ๆ ที่เพิ่มขึ้นเช่น Flow และ typescript ซึ่งเพิ่มการตรวจสอบประเภทแบบคงที่ให้กับจาวาสคริปต์


0

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

  • แทนที่จะคุณสามารถใช้if(myObj.hasSomeProperty()) if( myobj.prop !== undefined )นี้ BTW if( typeof myobj.prop !== 'undefined' )จะทำงานเฉพาะในโหมดที่ไม่เข้มงวดในโหมดเข้มงวดคุณจะต้องใช้

  • คุณสามารถถ่ายการตรวจสอบประเภทเพื่อแยกตัวตรวจสอบความถูกต้องออกได้ นี้มีผลประโยชน์ของความสามารถในการตรวจสอบครั้งเดียวข้ามอินเตอร์เฟซที่เป็นผู้ใหญ่เช่นif( is_valid( myobject ))ที่เริ่มต้นด้วยis_validif( !DEBUG ) return true;

  • บางครั้งมันก็สมเหตุสมผลที่จะทำการโคลนข้อมูลเข้าในรูปแบบมาตรฐานซึ่งในกรณีนี้คุณสามารถรวบรวมเป้าหมายการตรวจสอบความถูกต้องต่าง ๆ ลงในฟังก์ชัน / วัตถุการโคลน สำหรับ exmaple ในคอนสตรัคในทำเลที่สะดวกสามารถเรียกใช้ทั้งหมดที่ตรวจสอบต่าง ๆ ในสถานที่กลางmy_data = Data( myobj, otherstuff )Data

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

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