ทำไมการส่งผ่านฟังก์ชั่นที่ไม่ระบุชื่อขนาดใหญ่เป็นข้อโต้แย้งไปยังฟังก์ชั่นอื่น ๆ จึงได้รับการยอมรับใน JavaScript


27

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

อย่างไรก็ตามไลบรารีJavaScriptจำนวนมาก(jQuery, d3.js / NVD3.js) เพียงแค่ให้ตัวอย่างสองสามตัวอย่างใช้ฟังก์ชันขนาดใหญ่ด้วยวิธีนี้

ทำไมจึงเป็นที่ยอมรับอย่างกว้างขวางใน JavaScript? มันเป็นสิ่งที่เกี่ยวกับวัฒนธรรมหรือมีข้อได้เปรียบที่ฉันขาดไปซึ่งจะทำให้การใช้งานเป็นที่นิยมมากกว่าการประกาศฟังก์ชั่นที่มีชื่อ?


1
มันอาจจะมีจำนวนมากจะทำอย่างไรกับการใช้การปิด มันอาจจะเกี่ยวข้องกับการไม่ต้องการเปิดเผยฟังก์ชั่นที่เกิดขึ้นจริงกับโลกภายนอก (ซึ่งเป็นสาเหตุที่มันไม่ระบุชื่อ)
Robert Harvey

3
@RobertHarvey กล่าวอีกนัยหนึ่งก็คือวิธีแก้ปัญหาสำหรับ JavaScript ที่ไม่มีสาธารณะและส่วนบุคคล ?
Mason Wheeler

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

5
@MasonWheeler: ขึ้นอยู่กับมุมมองของคุณ โปรแกรมเมอร์ Scheme หรือ ECMAScript อาจพูดอย่างนั้นpublicและprivateเป็นวิธีแก้ปัญหาสำหรับการปิดไม่เหมาะสม
Jörg W Mittag

1
@ JörgWMittag Hooray สำหรับแร็กเก็ตผู้สนับสนุนภาษาอย่างเป็นทางการของXKCD 927!
Mason Wheeler

คำตอบ:


23

สามเหตุผลหลักที่ฉันนึกถึง:

  1. การเข้าถึงขอบเขตผู้ปกครอง
  2. ความเป็นส่วนตัว
  3. การลดชื่อที่กำหนดในขอบเขตที่สูงกว่า

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

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

ความเป็นส่วนตัว:รหัสภายในคำจำกัดความแบบไม่ระบุชื่อแบบอินไลน์มีความเป็นส่วนตัวมากกว่าและไม่สามารถเรียกได้ด้วยรหัสอื่น

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


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

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


ในฐานะนักพัฒนา C ++ เมื่อเร็ว ๆ นี้ย้ายมาที่ JS สำหรับงานของฉันจำนวนมากคำตอบนี้สมเหตุสมผลมากโดยเฉพาะจุด 'การเข้าถึงขอบเขตของผู้ปกครอง' - จริงๆแล้วมันมีพลังที่จะทำให้รหัสของคุณง่ายขึ้นอย่างมาก หนึ่ง nitpick - C ++ ให้การเข้าถึงขอบเขตของผู้ปกครองใน lambdas C ++ 11 :) แน่นอนว่า +1
ผู้บัญชาการผักชีซาลาแมนเด

8

ฟังก์ชั่นที่ไม่ระบุชื่อถูกใช้เพื่อวัตถุประสงค์อื่น ๆ อีกมากมายใน JavaScript กว่าจะเป็นภาษาส่วนใหญ่

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

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

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

นอกจากนี้ยังมีปัจจัยทางวัฒนธรรมและด้วยเหตุผลข้างต้นฟังก์ชั่นที่ไม่ระบุชื่อนั้นพบได้บ่อยใน JavaScript มากกว่าภาษาอื่น ๆ และมีการใช้งานอย่างสะดวกสบาย / หย่อนกว่าภาษาอื่น ๆ


โครงสร้างของฉันเองที่ไร้เดียงสาในการเข้ารหัส C ++ บางครั้งมีหลักการของการเข้ารหัสและการเรียกกลับจากเหตุการณ์ผ่าน JavaScript ผ่าน std :: function และ lambdas ในกรณีของฉันมันเป็นบางส่วนเพราะฉันทำรหัส UI ใน C ++ และไม่ต้องการทำการบล็อก ฉันอยากรู้ว่าการปฏิบัติของ JavaScript นั้นมีประโยชน์กับทุกคนตราบใดที่ภาษารองรับพวกเขาได้ดี
Katana314
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.