ฟังก์ชันจาวาสคริปต์ JavaScript ที่แสดงออก: ฟังก์ชัน Javascript ที่ส่งคืนค่าหลายค่าจากฟังก์ชัน

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

โดนัลด์ คนุธ

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

การใช้ฟังก์ชันที่ชัดเจนที่สุดคือการสร้างพจนานุกรมใหม่ การประดิษฐ์คำสำหรับร้อยแก้วของมนุษย์ธรรมดาเป็นรูปแบบที่ไม่ดี นี่เป็นสิ่งจำเป็นในภาษาการเขียนโปรแกรม

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

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

Var square = function(x) ( return x * x; ); console.log(สี่เหลี่ยม(12)); // → 144

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

ฟังก์ชันอาจมีหลายพารามิเตอร์หรือไม่มีเลยก็ได้ ในตัวอย่างต่อไปนี้ makeNoise ไม่มีรายการพารามิเตอร์ แต่ power มีสองรายการ:

Var makeNoise = function() ( console.log("อึ!"); ); ส่งเสียง(); // → คริยา! var power = function(ฐาน, เลขชี้กำลัง) ( var result = 1; for (var count = 0; count< exponent; count++) result *= base; return result; }; console.log(power(2, 10)); // → 1024

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

พารามิเตอร์และขอบเขตพารามิเตอร์ฟังก์ชันเป็นตัวแปรเดียวกัน แต่ค่าเริ่มต้นจะถูกตั้งค่าเมื่อมีการเรียกใช้ฟังก์ชันและไม่ได้อยู่ในโค้ด

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

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

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

Var x = "ภายนอก"; var f1 = function() ( var x = "ภายใน f1"; ); f1(); console.log(x); // → ภายนอก var f2 = function() ( x = "ภายใน f2"; ); f2(); console.log(x); // → ภายใน f2

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

JavaScript การกำหนดขอบเขตที่ซ้อนกันแยกความแตกต่างได้มากกว่าแค่ระหว่างตัวแปรส่วนกลางและตัวแปรท้องถิ่น ฟังก์ชั่นสามารถกำหนดได้ภายในฟังก์ชั่น ส่งผลให้มีระดับท้องถิ่นหลายระดับ

ตัวอย่างเช่น ฟังก์ชันที่ค่อนข้างไม่มีความหมายต่อไปนี้มีอีกสองฟังก์ชันอยู่ข้างใน:

ภูมิทัศน์ Var = function() ( var result = ""; var flat = function(size) ( for (var count = 0; count< size; count++) result += "_"; }; var mountain = function(size) { result += "/"; for (var count = 0; count < size; count++) result += """; result += "\\"; }; flat(3); mountain(4); flat(6); mountain(1); flat(1); return result; }; console.log(landscape()); // → ___/""""\______/"\_

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

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

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

มีค่าเท่ากับ 1; ( var some = 2; // ทำบางสิ่งกับตัวแปรบางอย่าง... ) // ออกจากบล็อก...

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

หากสิ่งนี้ดูแปลกสำหรับคุณ คุณไม่ใช่คนเดียวที่คิดเช่นนั้น ในเวอร์ชัน JavaScript 1.7 ปรากฏขึ้น คำสำคัญ Let ซึ่งทำงานเหมือนกับ var แต่สร้างตัวแปรที่อยู่ภายในบล็อกที่กำหนด ไม่ใช่แค่ฟังก์ชัน

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

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

Var launchMissiles = function(value) ( ​​​​missileSystem.launch("or!"); ); ถ้า (safeMode) launchMissiles = ฟังก์ชั่น (ค่า) (/* ยกเลิก */);

ในบทที่ 5 เราจะพูดถึงสิ่งมหัศจรรย์ที่คุณสามารถทำได้โดยการส่งการเรียกใช้ฟังก์ชันไปยังฟังก์ชันอื่นๆ

การประกาศฟังก์ชัน มีเวอร์ชันที่สั้นกว่าของนิพจน์ “var square = function...” คำสำคัญฟังก์ชันสามารถนำมาใช้ที่จุดเริ่มต้นของคำสั่ง:

ฟังก์ชัน สแควร์(x) ( ส่งคืน x * x; )

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

Console.log("อนาคตพูดว่า:", อนาคต()); function Future() ( return "เรายังไม่มีรถบินได้"; )

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

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

ตัวอย่างฟังก์ชัน() ( function a() () // Normal if (something) ( function b() () // Ay-yay-yay! ) )

Call Stack การดูรายละเอียดว่าลำดับการดำเนินการทำงานอย่างไรกับฟังก์ชันต่างๆ ให้ละเอียดยิ่งขึ้น ที่นี่ โปรแกรมง่ายๆด้วยการเรียกใช้ฟังก์ชันหลายรายการ:

ฟังก์ชั่น ทักทาย(ใคร) ( console.log("Hello, " + who); ) ทักทาย("Semyon"); console.log("โปเกดา");

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

ซึ่งสามารถแสดงเป็นแผนผังได้ดังนี้:

ทักทายด้านบน console.log ทักทายด้านบน console.log ด้านบน

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

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

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

ฟังก์ชั่นไก่() ( กลับไข่(); ) ฟังก์ชั่นไข่() ( กลับไก่(); ) console.log(chicken() + " มาก่อน"); // → ??

อาร์กิวเมนต์เสริม รหัสต่อไปนี้ถูกต้องตามกฎหมายอย่างสมบูรณ์และทำงานได้โดยไม่มีปัญหา:

การแจ้งเตือน("สวัสดี", "สวัสดีตอนเย็น", "สวัสดีทุกคน!");

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

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

ข้อเสียของวิธีนี้คือเป็นไปได้ - และมีแนวโน้ม - ที่จะส่งอาร์กิวเมนต์จำนวนที่ไม่ถูกต้องไปยังฟังก์ชันโดยไม่มีใครบ่นเกี่ยวกับมัน

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

กำลังของฟังก์ชัน(ฐาน, เลขชี้กำลัง) ( ถ้า (เลขชี้กำลัง == ไม่ได้กำหนด) เลขชี้กำลัง = 2; ผลลัพธ์ var = 1; สำหรับ (จำนวนนับ = 0; นับ< exponent; count++) result *= base; return result; } console.log(power(4)); // → 16 console.log(power(4, 3)); // → 64

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

Console.log("R", 2, "D", 2); // → R 2 D 2

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

ตัวอย่างต่อไปนี้แสดงให้เห็นถึงปัญหานี้ ประกาศฟังก์ชัน wrapValue ซึ่งสร้างตัวแปรท้องถิ่น จากนั้นจะส่งกลับฟังก์ชันที่อ่านตัวแปรท้องถิ่นนี้และส่งกลับค่าของมัน

ฟังก์ชั่น wrapValue(n) ( var localVariable = n; return function() ( return localVariable; ); ) var wrap1 = wrapValue(1); var wrap2 = wrapValue (2); console.log(wrap1()); // → 1 console.log(wrap2()); // → 2

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

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

ด้วยการปรับเปลี่ยนเล็กน้อย เราจะเปลี่ยนตัวอย่างของเราให้เป็นฟังก์ชันที่คูณตัวเลขด้วยจำนวนที่กำหนดใดๆ

ตัวคูณฟังก์ชัน(ตัวประกอบ) ( return function(number) ( return number * factor; ); ) var สองครั้ง = ตัวคูณ(2); console.log(สองครั้ง(5)); // → 10

ไม่จำเป็นต้องใช้ตัวแปรแยกเช่น localVariable จากตัวอย่าง wrapValue อีกต่อไป เนื่องจากพารามิเตอร์นั้นเป็นตัวแปรท้องถิ่น

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

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

การเรียกซ้ำฟังก์ชัน A อาจเรียกตัวเองได้ดีตราบใดที่ดูแลไม่ให้ล้นสแต็ก ฟังก์ชันนี้เรียกว่าแบบเรียกซ้ำ นี่คือตัวอย่างการใช้วิธียกกำลังแบบอื่น:

ฟังก์ชั่น power(base, exponent) ( if (exponent == 0) return 1; else return base * power(base, exponent - 1); ) console.log(power(2, 3)); // → 8

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

อย่างไรก็ตาม มีปัญหาในการใช้งานนี้: สภาพแวดล้อมปกติ JavaScript ช้ากว่าเวอร์ชันที่มีการวนซ้ำ 10 เท่า การเดินผ่านลูปมีราคาถูกกว่าการเรียกใช้ฟังก์ชัน

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

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

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

แน่นอนว่าเราไม่ควรละเลยประสิทธิภาพโดยสิ้นเชิงในทันที ในหลายกรณี เช่นเดียวกับการยกกำลัง เราไม่ได้รับความเรียบง่ายมากนักจากโซลูชันที่หรูหรา บางครั้ง โปรแกรมเมอร์ที่มีประสบการณ์มองเห็นได้ทันทีว่าแนวทางง่ายๆ นั้นเร็วไม่พอ

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

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

ปริศนา: คุณสามารถได้จำนวนอนันต์โดยเริ่มจากเลข 1 แล้วบวก 5 หรือคูณด้วย 3 เราจะเขียนฟังก์ชันที่พยายามค้นหาลำดับของการบวกและการคูณเมื่อกำหนดตัวเลขไว้ได้อย่างไร ที่นำไปสู่หมายเลขที่กำหนด? ตัวอย่างเช่น สามารถรับเลข 13 ได้โดยการคูณ 1 ด้วย 3 ก่อนแล้วจึงบวก 5 สองครั้ง และหมายเลข 15 ไม่สามารถรับด้วยวิธีนี้ได้เลย

วิธีแก้ปัญหาแบบเรียกซ้ำ:

ฟังก์ชั่น findSolution(target) ( function find(start, history) ( if (start == target) return history; else if (start > target) return null; else return find(start + 5, "(" + history + " + 5)") || find(start * 3, "(" + history + " * 3)"); ) ส่งคืน find(1, "1"); ) console.log(findSolution(24)); // → (((1 * 3) + 5) * 3)

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

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

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

เพื่อให้เข้าใจได้ดีขึ้นว่าฟังก์ชันนี้บรรลุผลตามที่ต้องการได้อย่างไร มาดูการเรียกฟังก์ชันเพื่อหาคำตอบของเลข 13 กัน

ค้นหา(1, "1") ค้นหา(6, "(1 + 5)") ค้นหา(11, "((1 + 5) + 5)") ค้นหา(16, "(((1 + 5) + 5) ) + 5)") ค้นหาใหญ่เกินไป (33, "(((1 + 5) + 5) * 3)") ค้นหาใหญ่เกินไป (18, "((1 + 5) * 3)") ค้นหาใหญ่เกินไป ( 3, "(1 * 3)") พบ (8, "((1 * 3) + 5)") พบ (13, "(((1 * 3) + 5) + 5)") พบแล้ว!

การเยื้องแสดงความลึกของ call stack ในครั้งแรก ฟังก์ชัน find จะเรียกตัวเองสองครั้งเพื่อตรวจสอบวิธีแก้ปัญหาที่เริ่มต้นด้วย (1 + 5) และ (1 * 3) การเรียกครั้งแรกจะค้นหาโซลูชันที่เริ่มต้นด้วย (1 + 5) และใช้การเรียกซ้ำเพื่อตรวจสอบโซลูชันทั้งหมดที่สร้างตัวเลขน้อยกว่าหรือเท่ากับจำนวนที่ต้องการ ไม่พบมันและส่งคืนค่าว่าง จากนั้นตัวดำเนินการ || และไปยังการเรียกใช้ฟังก์ชันที่ตรวจสอบตัวเลือก (1 * 3) เราโชคดีที่นี่ เพราะในการเรียกซ้ำครั้งที่สามเราได้รับ 13 การเรียกนี้จะส่งคืนสตริง และแต่ละ || แต่ละตัว ระหว่างทางมันผ่านเส้นนี้สูงขึ้นส่งผลให้ได้ผลลัพธ์กลับมา

ฟังก์ชันที่เพิ่มขึ้น มีวิธีที่เป็นธรรมชาติสองวิธีมากหรือน้อยในการแนะนำฟังก์ชันต่างๆ เข้าสู่โปรแกรม

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

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

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

007 วัว 011 ไก่

แน่นอนว่าเราต้องการฟังก์ชันที่มีอาร์กิวเมนต์สองตัว มาเริ่มเขียนโค้ดกัน
// พิมพ์ฟังก์ชัน FarmInventory printFarmInventory (วัว, ไก่) ( var cowString = String (วัว); while (cowString.length< 3) cowString = "0" + cowString; console.log(cowString + " Коров"); var chickenString = String(chickens); while (chickenString.length < 3) chickenString = "0" + chickenString; console.log(chickenString + " Куриц"); } printFarmInventory(7, 11);

ถ้าเราบวก .length เข้ากับสตริง เราจะได้ความยาวของมัน ปรากฎว่า ในขณะที่วนซ้ำเพิ่มศูนย์นำหน้าให้กับตัวเลขจนกว่าคุณจะได้สตริง 3 ตัวอักษร

พร้อม! แต่ในขณะที่เรากำลังจะส่งรหัสไปให้ชาวนา (พร้อมกับเช็คอันหนักหน่วงด้วย) เขาก็โทรมาบอกเราว่าเขามีหมูอยู่ในฟาร์ม และเราขอเพิ่มการแสดงจำนวนหมูลงในฟาร์มได้ไหม โปรแกรม?

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

// เอาต์พุตพร้อมฟังก์ชันการเพิ่มศูนย์และป้ายกำกับ printZeroPaddedWithLabel(number, label) ( var numberString = String(number); while (numberString.length)< 3) numberString = "0" + numberString; console.log(numberString + " " + label); } // вывестиИнвентаризациюФермы function printFarmInventory(cows, chickens, pigs) { printZeroPaddedWithLabel(cows, "Коров"); printZeroPaddedWithLabel(chickens, "Куриц"); printZeroPaddedWithLabel(pigs, "Свиней"); } printFarmInventory(7, 11, 3);

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

// เพิ่มฟังก์ชัน Zero zeroPad(หมายเลข, ความกว้าง) ( var string = String(number); while (string.length< width) string = "0" + string; return string; } // вывестиИнвентаризациюФермы function printFarmInventory(cows, chickens, pigs) { console.log(zeroPad(cows, 3) + " Коров"); console.log(zeroPad(chickens, 3) + " Куриц"); console.log(zeroPad(pigs, 3) + " Свиней"); } printFarmInventory(7, 16, 3);

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

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

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

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

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

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

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

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

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

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

แบบฝึกหัดขั้นต่ำ ในบทที่แล้ว เราได้กล่าวถึงฟังก์ชัน Math.min ซึ่งส่งกลับอาร์กิวเมนต์ที่น้อยที่สุด ตอนนี้เราสามารถเขียนฟังก์ชันดังกล่าวได้ด้วยตัวเอง เขียนฟังก์ชัน min ที่รับสองอาร์กิวเมนต์และส่งกลับค่าต่ำสุด

Console.log(นาที(0, 10)); // → 0 console.log(นาที(0, -10)); // → -10

การเรียกซ้ำ เราพบว่าตัวดำเนินการ % (โมดูโล) สามารถใช้เพื่อกำหนดว่าตัวเลข (%2) เป็นเลขคู่หรือไม่ นี่เป็นอีกวิธีหนึ่งในการกำหนด:

ศูนย์คือเลขคู่
หน่วยมันแปลกๆ
จำนวน N ใดๆ มีความเท่าเทียมกันเหมือนกับ N-2

เขียนฟังก์ชันแบบเรียกซ้ำ isEven ตามกฎเหล่านี้ ต้องยอมรับตัวเลขและส่งกลับค่าบูลีน

ทดสอบที่ 50 และ 75 ลองให้ -1 ทำไมเธอถึงทำตัวแบบนี้? เป็นไปได้ไหมที่จะแก้ไขมัน?

ทดสอบบน 50 และ 75 ดูว่ามันทำงานอย่างไรใน -1 ทำไม คุณช่วยคิดวิธีแก้ปัญหานี้ได้ไหม?

Console.log(isEven(50)); // → true console.log(isEven(75)); // → false console.log(isEven(-1)); // → ??

นับถั่ว.

สามารถรับหมายเลขอักขระ N ของสตริงได้โดยการเพิ่ม .charAt(N) (“string”.charAt(5)) ลงไป - ในวิธีที่คล้ายกันในการรับความยาวของสตริงโดยใช้ .length ค่าที่ส่งคืนจะเป็นสตริงที่ประกอบด้วยอักขระหนึ่งตัว (เช่น "k") อักขระตัวแรกของสตริงมีตำแหน่ง 0 ซึ่งหมายความว่าอักขระตัวสุดท้ายจะมีตำแหน่ง string.length - 1 กล่าวอีกนัยหนึ่ง สตริงของอักขระสองตัวมีความยาว 2 และตำแหน่งของอักขระจะเป็น 0 และ 1

เขียนฟังก์ชัน countB ที่รับสตริงเป็นอาร์กิวเมนต์และส่งกลับจำนวนอักขระ "B" ที่มีอยู่ในสตริง

จากนั้นเขียนฟังก์ชันที่เรียกว่า countChar ซึ่งทำงานคล้ายกับ countBs แต่รับพารามิเตอร์ตัวที่สอง ซึ่งเป็นอักขระที่เราจะค้นหาในสตริง (แทนที่จะนับเพียงจำนวนอักขระ "B") เมื่อต้องการทำเช่นนี้ ให้ทำฟังก์ชัน countBs ใหม่

ฟังก์ชั่นเป็นหนึ่งในองค์ประกอบที่สำคัญที่สุดของโค้ดใน JavaScript

ฟังก์ชันประกอบด้วยชุดคำสั่งและมักจะดำเนินการอย่างใดอย่างหนึ่ง งานเฉพาะ(เช่น การบวกเลข การคำนวณราก เป็นต้น)

รหัสที่วางอยู่ในฟังก์ชันจะถูกดำเนินการหลังจากการเรียกฟังก์ชันนี้อย่างชัดเจนเท่านั้น

การประกาศฟังก์ชั่น

1. ไวยากรณ์:

//การประกาศฟังก์ชัน functionFunctionname(ln1, ln2)( Function code) //เรียกฟังก์ชันFunctionname(ln1,lr2);

2. ไวยากรณ์:

//การประกาศฟังก์ชัน var function name=function(ln1, ln2)(Function code) //เรียกฟังก์ชันชื่อฟังก์ชัน(ln1,lr2);

functionname ระบุชื่อของฟังก์ชัน แต่ละฟังก์ชันบนเพจต้องมีชื่อไม่ซ้ำกัน ชื่อฟังก์ชันต้องระบุเป็นตัวอักษรละตินและต้องไม่ขึ้นต้นด้วยตัวเลข

ln1 และ ln2 เป็นตัวแปรหรือค่าที่สามารถส่งผ่านเข้าสู่ฟังก์ชันได้ สามารถส่งตัวแปรไปยังแต่ละฟังก์ชันได้ไม่จำกัดจำนวน

โปรดทราบ: แม้ว่าจะไม่มีการส่งตัวแปรไปยังฟังก์ชันก็ตาม อย่าลืมใส่วงเล็บ "()" หลังชื่อฟังก์ชัน

โปรดทราบว่าชื่อฟังก์ชันใน JavaScript จะต้องตรงตามตัวพิมพ์เล็กและตัวพิมพ์ใหญ่

ตัวอย่างฟังก์ชันจาวาสคริปต์

ฟังก์ชัน messageWrite() ในตัวอย่างด้านล่างจะถูกดำเนินการหลังจากคลิกปุ่มแล้วเท่านั้น

โปรดทราบว่าตัวอย่างนี้ใช้เหตุการณ์ onclick เหตุการณ์จาวาสคริปต์จะกล่าวถึงรายละเอียดในหนังสือเรียนเล่มนี้ต่อไป

// ฟังก์ชันเขียนข้อความไปยังฟังก์ชันเพจ messageWrite() ( document.write("ข้อความนี้ถูกเขียนไปยังเพจโดยใช้ JavaScript!"); )

การส่งผ่านตัวแปรไปยังฟังก์ชัน

คุณสามารถส่งผ่านตัวแปรไปยังฟังก์ชันได้ไม่จำกัดจำนวน

โปรดทราบ: การปรับเปลี่ยนทั้งหมดที่มีตัวแปรภายในฟังก์ชันนั้นไม่ได้ดำเนินการกับตัวแปรโดยตรง แต่เป็นการคัดลอก ดังนั้นเนื้อหาของตัวแปรจึงไม่เปลี่ยนแปลงอันเป็นผลมาจากการดำเนินการฟังก์ชัน

/* มากำหนดฟังก์ชันที่บวก 10 เข้ากับตัวแปรที่ส่งผ่านแล้วแสดงผลลัพธ์ในหน้า */ function plus(a)( a=a+10; document.write("Function output: " + a+"
"); ) var a=25; document.write("ค่าของตัวแปรก่อนการเรียกใช้ฟังก์ชัน: "+a+"
"); // เรียกใช้ฟังก์ชันโดยส่งผ่านตัวแปร a plus(a); document.write("ค่าของตัวแปรหลังจากเรียกใช้ฟังก์ชัน: "+a+"
");

ดูด่วน

หากต้องการเข้าถึงตัวแปรร่วมจากฟังก์ชันแทนที่จะเป็นสำเนา ให้ใช้ window.variable_name

ฟังก์ชั่น plus(a)( window.a=a+10; ) var a=25; document.write("ค่าของตัวแปรก่อนการเรียกใช้ฟังก์ชัน: "+a+"
"); plus(a); document.write("ค่าของตัวแปรหลังจากเรียกใช้ฟังก์ชัน: "+a+"
");

ดูด่วน

คำสั่งส่งคืน

ด้วยคำสั่ง return คุณสามารถคืนค่าจากฟังก์ชันได้

//ฟังก์ชัน sum ส่งกลับผลรวมของตัวแปรที่ส่งไปให้ function sum(v1,v2)( return v1+v2; ) document.write("5+6=" + sum(5,6) + "
"); document.write("10+4=" + ผลรวม (10,4) + "
");

ดูด่วน

ฟังก์ชั่นในตัว

นอกเหนือจากฟังก์ชันที่ผู้ใช้กำหนดแล้ว JavaScript ยังมีฟังก์ชันในตัวอีกด้วย

ตัวอย่างเช่น ฟังก์ชัน isFinite ในตัวช่วยให้คุณตรวจสอบว่าค่าที่ส่งเป็นตัวเลขที่ถูกต้องหรือไม่

Document.write(isFinite(40)+"
"); document.write(isFinite(-590)+"
"); document.write(isFinite(90.33)+"
"); document.write(isFinite(NaN)+"
"); document.write(isFinite("นี่คือสตริง")+"
");

ดูด่วน

บันทึก: รายการทั้งหมดในตัว ฟังก์ชันจาวาสคริปต์คุณสามารถค้นหาได้ในของเรา

ตัวแปรท้องถิ่นและระดับโลก

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

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

ตัวแปรที่สร้างขึ้นภายนอกโค้ดฟังก์ชันเรียกว่าตัวแปรโกลบอล ซึ่งตัวแปรดังกล่าวสามารถเข้าถึงได้จากทุกที่ในโค้ด

หากคุณประกาศตัวแปรโดยไม่มี var ภายในฟังก์ชัน ตัวแปรนั้นจะกลายเป็นแบบโกลบอลด้วย

ตัวแปรโกลบอลจะถูกทำลายหลังจากปิดเพจแล้วเท่านั้น

//ประกาศตัวแปรโกลบอล var1 และ var2 var var1="var1 มีอยู่"; วาร์ var2; function func1() ( //กำหนดค่า var2 ภายในฟังก์ชัน func1 var var2="var2 existing"; ) //จากฟังก์ชันอื่น ให้พิมพ์เนื้อหาของตัวแปร var1 และ var2 ไปยังฟังก์ชันเพจ func2() ( //Print เนื้อหาของตัวแปร var1 document.write( var1 + "
"); //ส่งออกเนื้อหาของตัวแปร var2 document.write(var2); )

ดูด่วน

โปรดทราบว่าเมื่อพิมพ์ลงหน้าจอ var2 จะมีค่าว่างเนื่องจาก func1 ทำงานบน "เวอร์ชัน" ในเครื่องของ var2

การใช้ฟังก์ชันที่ไม่ระบุชื่อ

ฟังก์ชั่นที่ไม่มีชื่อเมื่อประกาศจะถูกเรียกว่าไม่ระบุชื่อ

โดยพื้นฐานแล้วฟังก์ชันนิรนามจะถูกประกาศว่าจะไม่ถูกเรียกจากโค้ดเหมือนกับฟังก์ชันปกติในภายหลัง แต่จะถูกส่งผ่านไปยังฟังก์ชันอื่นเป็นพารามิเตอร์

ฟังก์ชั่น arrMap(arr,func)( var res=new Array; for (var i=0;i