วิธีหลีกเลี่ยง“ ความผิดพลาดทางภาษาแบบไดนามิก” โดยทั่วไปได้อย่างไร?


42

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

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

วิธีทำให้รัดกุมยิ่งขึ้น:

  • คุณเข้าใกล้โครงการ JavaScript (หรือภาษาไดนามิกอื่น ๆ สำหรับเรื่องนั้น) ด้วย ~ 2000 LOC อย่างไร
  • มีเครื่องมือในการป้องกันไม่ให้ฉันทำผิดพลาดเหล่านั้นหรือไม่? ฉันลองใช้การไหลผ่าน Facebook และ JSHint ซึ่งค่อนข้างจะช่วยได้ แต่ไม่จับความผิดพลาด

2
ถึงแม้ว่าจะมีวิธีการที่จะลดค่าใช้จ่ายที่มีมีค่าใช้จ่าย
dcastro

29
ฉันจะลองเขียนโปรแกรมของคุณในภาษาที่พิมพ์แบบคงที่ที่รวบรวมไปยังจาวาสคริปต์เช่น typescript, Scala.js หรือ Elm
dcastro

6
การทดสอบการทดสอบการทดสอบเพิ่มเติมและรายงานความครอบคลุม
njzk2

7
~ 2000 LOC เป็นโครงการขนาดเล็ก มันควรจะพอดีกับสิ่งที่ภาษาแบบไดนามิกทำได้อย่างง่ายดายและดี หากคุณกำลังดิ้นรนกับโครงการขนาดดังกล่าวคุณจะมีปัญหาพื้นฐานกับทักษะการเขียนโปรแกรมของคุณมากกว่าสิ่งใดที่เกี่ยวข้องกับภาษาไดนามิกโดยเฉพาะ
Jack Aidley

5
@JackAidley ไม่เห็นด้วย OP ใช้เพื่อมุ่งเน้นไปที่ปัญหาระดับสูงและไม่ได้ระบุว่าตัวสะกดถูกต้องหรือไม่ นั่นคือทักษะการเขียนโปรแกรม การตรวจสอบให้แน่ใจว่าการสะกดคำที่ถูกต้องสามารถทำได้โดยการใช้ตัวคั่นกลางและ / หรือการสนับสนุนเครื่องมือ
mucaho

คำตอบ:


37

พูดถึง JavaScript โดยเฉพาะคุณสามารถใช้TypeScriptแทน มันมีบางสิ่งที่คุณพูดถึง การอ้างถึงเว็บไซต์:

ประเภทช่วยให้นักพัฒนา JavaScript สามารถใช้เครื่องมือและแนวทางการพัฒนาที่มีประสิทธิผลสูงเช่นการตรวจสอบแบบคงที่และการสร้างรหัสใหม่เมื่อพัฒนาแอปพลิเคชัน JavaScript

และมันก็เป็นเพียงชุดของ JS ซึ่งหมายความว่ารหัสที่มีอยู่บางส่วนของคุณจะทำงานกับ TS ได้ดี:

TypeScript เริ่มต้นจากไวยากรณ์และความหมายเดียวกันกับที่ผู้พัฒนา JavaScript หลายล้านคนรู้จักในวันนี้ ใช้รหัส JavaScript ที่มีอยู่รวมไลบรารี JavaScript ที่เป็นที่นิยมและเรียกรหัส TypeScript จาก JavaScript


11
... และ TypeScript นั้นเป็น Ecmascript 6 โดยพื้นฐานแล้ว
Robert Harvey

11
เอ่ออ้างว่าเจ็บ มันแสดงให้เห็นว่า Microsoft เป็น บริษัท ที่ใช้ภาษาแบบคงที่ซึ่งไม่เข้าใจภาษาแบบไดนามิกเสมอ "ประเภทเปิดใช้งาน ... การสร้างรหัสใหม่" หรือไม่ จริงๆ? แผนกประชาสัมพันธ์ของ Microsoft ทราบหรือไม่ว่าการสร้างรหัสซ้ำเป็นวิธีปฏิบัตินั้นถูกคิดค้นใน Smalltalk (ภาษาไดนามิก) และมีอยู่ก่อนหน้านั้นใน Forth (เป็นภาษาที่ไม่มีการพิมพ์)? เครื่องมือการรีแฟคเตอร์อัตโนมัติครั้งแรกนั้นเป็นส่วนหนึ่งของ Smalltalk IDE ก่อนที่ภาษาแบบคงที่จะมี IDE Smalltalk IDEs ที่ทันสมัยนั้นมีเครื่องมือการรีแฟคเตอร์อย่างน้อยก็ทรงพลังหากไม่มากกว่า Java, C # และ C ++? C'mon
Jörg W Mittag

5
TypeScript เป็นภาษาที่ยอดเยี่ยมในตัวเองทำไมคุณต้องลองและผลักดันมันด้วยเรื่องไร้สาระเช่นนี้?
Jörg W Mittag

29
@ Jörgฉันไม่รู้เรื่อง Smalltalk มากพอ แต่ IDE ทุกตัวสำหรับ JavaScript หรือ Python ที่ฉันเคยเห็นมีหลายไมล์ที่ IDE ที่ดีสำหรับ Java หรือ C # สามารถทำได้ นอกจากนี้ยังมีบางสิ่งที่เป็นไปไม่ได้ธรรมดาที่จะทำในภาษาไดนามิก (บางส่วนของการรีแฟคเจอริ่งที่นิยมมากที่สุด): สมมติว่าคุณมีฟังก์ชั่นสาธารณะfoo(x) { return x.bar;}หรืออะไรทำนองนั้น เนื่องจากไม่มีข้อมูลประเภทและฟังก์ชั่นเป็นแบบสาธารณะ (ด้วยเหตุนี้คุณจึงไม่ทราบผู้โทรทั้งหมด) จึงเป็นไปไม่ได้ที่คุณจะทราบว่าควรเปลี่ยนชื่อบาร์เป็น baz หรือไม่ถ้าคุณเปลี่ยนชื่อบางคลาส
Voo

10
คำตอบนี้บอกว่าการแก้ปัญหา "ความผิดพลาดของภาษาแบบไดนามิก" ไม่ได้เป็นการใช้ภาษาแบบไดนามิกเลย
bgusach

19

มีวิธีการบางอย่างที่สามารถช่วย:

การทดสอบหน่วย

เขียนการทดสอบหน่วยที่เป็นไปได้ การพึ่งพาการทดสอบด้วยตนเองหรือการค้นหาข้อบกพร่องในป่าอย่างโดดเดี่ยวนั้นเป็นเรื่องที่พลาดไม่ได้

ใช้กรอบงาน

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

ต้องการ CSS / ภาษาระดับสูง

ที่ซึ่งคุณสามารถยกระดับการทำงานให้กับ CSS หรือภาษาระดับสูงที่คุณเขียน

refactor

Refactor เพื่อลดปริมาณของรหัส รหัสน้อย = สถานที่น้อยลงสำหรับสิ่งที่ผิดพลาด

นำมาใช้ใหม่

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

IDEs

IDEs ที่ทันสมัยโดยทั่วไปมีการสนับสนุน Javascript อย่างน้อย เครื่องมือแก้ไขข้อความบางตัวยังรับรู้ Javascript ด้วย


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

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

4
"ชอบ CSS / ภาษาระดับสูง" - ฉันไม่เข้าใจจริงๆว่าบิตนี้มีความหมายอย่างไรกับ JavaScript: คุณกำลังบอกว่าจะย้ายองค์ประกอบ (เช่นภาพเคลื่อนไหวหรืออาจเป็นภาพเคลื่อนไหว) ไปยังสไตล์ชีตแทนที่จะเป็นรหัส JS ใช่หรือไม่ CSS เกี่ยวข้องกับภาษาระดับสูงอย่างไร
Anotherdave

@anotherdave สิ่งที่เคยเป็นโดเมน Javascript สามารถทำได้ใน CSS3 ฟังก์ชั่นบางอย่างอาจถูกย้ายไปยังภาษาระดับสูงขึ้นซึ่งจะต้องมีการควบคุมที่เข้มงวดมากขึ้น
Robbie Dee

4
@anotherdave สิ่งที่คนส่วนใหญ่พยายามทำกับ JavaScript นั้นไม่เกี่ยวข้องและไม่เหมาะสม ไลบรารีที่มีเครื่องมือภาษามาตรฐานกรอบงานที่ให้องค์ประกอบ HTML มาตรฐานที่มีเพิ่มอีกเล็กน้อยรหัสที่จำลองฟังก์ชันการทำงานขั้นพื้นฐานเช่นแองเคอร์การจำลอง MVC การใส่สไตล์การปรับใช้ DOM, AJAX abstraction, การแสดงวัตถุที่ไม่สำคัญ เป็นประโยชน์ต่อผู้ใช้ ... คุณควรลดจำนวน JS ที่คุณเขียนให้น้อยที่สุด หากคุณสามารถทำได้โดยไม่มี JS ให้ทำโดยไม่มี JS
bjb568

2

หนึ่งในเครื่องมือที่ไม่ได้รับการกล่าวถึงเลยเป็นเรื่องง่ายไฟล์ท้องถิ่นหรือโครงการทั้งการค้นหาข้อความ

มันฟังดูง่าย แต่เมื่อคุณรวมการแสดงออกปกติคุณสามารถทำพื้นฐานการกรองขั้นสูงบางอย่างเช่นค้นหาคำที่อยู่ในเอกสารหรือซอร์สโค้ด

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


2
grepไปไกล นอกจากว่าคุณจะไม่ทำสิ่งที่มีพลังแปลก ๆ อย่างไรก็ตามมันให้ความรู้สึกแบบแมนนวลถ้าคุณคุ้นเคยกับ IDE สำหรับภาษาที่พิมพ์คงที่
bgusach

1

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

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

คำแนะนำที่สองของฉันคือการดำเนินการตรวจสอบให้มากที่สุด เราปฏิบัติตามมาตรฐาน AirBnB และใช้ eslint บนฐานรหัสทั้งหมดของเรา Commit hooks ตรวจสอบว่าเราปฏิบัติตามมาตรฐานเสมอ เรามีแบตเตอรีและการทดสอบการยอมรับตามธรรมชาติและการคอมมิททั้งหมดจะต้องได้รับการตรวจสอบโดยเพื่อน

การสลับจากตัวแก้ไขข้อความ (Sublime Text) ไปเป็น IDE ที่เหมาะสม (WebStorm) ทำให้การทำงานกับโค้ดโดยทั่วไปง่ายขึ้น WebStorm จะใช้ JSDoc เพื่อให้คำแนะนำเกี่ยวกับประเภทพารามิเตอร์ที่คาดหวังและเพิ่มข้อผิดพลาดหากคุณระบุประเภทที่ไม่ถูกต้องหรือใช้ค่าตอบแทนในทางที่ผิด

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

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


0

คำตอบของฉันสำหรับคำถาม“ คุณจะทำโครงการ JavaScript (หรือภาษาไดนามิกอื่น ๆ สำหรับเรื่องนั้น) ด้วย ~ 2000 LOC ได้อย่างไร”

ฉันพัฒนาแอปพลิเคชันในรูปแบบ PDF ฉันเข้าใกล้โครงการพัฒนาซอฟต์แวร์จาวาสคริปต์ของฉัน (ไม่คำนึงถึงขนาดของซอร์สโค้ด) โดยใช้องค์ประกอบสุทธิและหมายเหตุประกอบของ Petri วิธีนี้ไม่ได้เชื่อมโยงกับเทคโนโลยีภาษาการเขียนโปรแกรมเฉพาะใด ๆ ดังนั้นมันอาจถูกใช้สำหรับ“ ภาษาโปรแกรม” อื่น ๆ

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

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

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

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