คำอธิบายโดยละเอียดเกี่ยวกับการสร้างแลนดิ้งเพจ Adobe Muse แลนดิ้งเพจคืออะไร? ปัจจัยสามประการมีความสำคัญสำหรับพวกเขา

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

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

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

แทบทุกเวลาที่คุณใช้โครงสร้าง JavaScript ที่มีวงเล็บคู่ - () - และคุณไม่ได้ใช้โครงสร้างภาษาในตัวทั่วไป เช่น for loop ในขณะที่ หรือ do... While loop หรือ if ..else คำสั่ง คุณกำลังใช้ฟังก์ชัน

ฟังก์ชั่นเบราว์เซอร์ในตัว

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

Var myText = "ฉันเป็นสตริง"; var newString = myText.replace("string", "ไส้กรอก"); console.log(สตริงใหม่); // ฟังก์ชันสตริงแทนที่() รับสตริง // แทนที่สตริงย่อยหนึ่งด้วยอีกสตริงหนึ่ง และส่งคืน // สตริงใหม่ที่มีการแทนที่

หรือทุกครั้งที่เราจัดการอาร์เรย์:

Var myArray = ["ฉัน", "ความรัก", "ช็อคโกแลต", "กบ"]; var madeAString = myArray.join(" "); console.log(ทำAString); // ฟังก์ชัน join() รับอาร์เรย์ รวม // รายการอาร์เรย์ทั้งหมดเข้าด้วยกันเป็นสตริงเดียว // และส่งกลับสตริงใหม่นี้

หรือทุกครั้งที่เราสร้างตัวเลขสุ่ม:

วาร์ myNumber = Math.random(); // ฟังก์ชัน Random() สร้างตัวเลขสุ่ม // ระหว่าง 0 ถึง 1 และส่งคืน // หมายเลขนั้น

เรากำลังใช้ฟังก์ชัน!

หมายเหตุ: คุณสามารถป้อนบรรทัดเหล่านี้ลงในคอนโซล JavaScript ของเบราว์เซอร์ของคุณเพื่อทำความคุ้นเคยกับฟังก์ชันการทำงานอีกครั้ง หากจำเป็น

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

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

ฟังก์ชันเทียบกับวิธีการ

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

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

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

ฟังก์ชั่นที่กำหนดเอง

จนถึงตอนนี้คุณเคยเห็นฟังก์ชันที่กำหนดเองมากมายในหลักสูตร - ฟังก์ชั่นที่กำหนดไว้ในโค้ดของคุณ ไม่ใช่ในเบราว์เซอร์ เมื่อใดก็ตามที่คุณเห็นชื่อที่กำหนดเองโดยมีวงเล็บต่อจากนั้น แสดงว่าคุณกำลังใช้ฟังก์ชันที่กำหนดเอง ในการสุ่มของเรา ตัวอย่าง canvas-circles.html (ดูทั้งหมด) จากบทความลูปของเรา เราได้รวมฟังก์ชัน Draw() แบบกำหนดเองที่มีลักษณะดังนี้:

ฟังก์ชั่นวาด() ( ctx.clearRect(0,0,WIDTH,HEIGHT); for (var i = 0; i< 100; i++) { ctx.beginPath(); ctx.fillStyle = "rgba(255,0,0,0.5)"; ctx.arc(random(WIDTH), random(HEIGHT), random(50), 0, 2 * Math.PI); ctx.fill(); } }

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

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

ฟังก์ชั่นสุ่ม(ตัวเลข) ( return Math.floor(Math.random()*number); )

เราต้องการฟังก์ชันนี้เนื่องจากฟังก์ชัน Math.random() ในตัวของเบราว์เซอร์สร้างเฉพาะตัวเลขทศนิยมแบบสุ่มระหว่าง 0 ถึง 1 เท่านั้น เราต้องการตัวเลขสุ่มจำนวนเต็มระหว่าง 0 ถึงตัวเลขที่ระบุ

การเรียกใช้ฟังก์ชัน

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

ฟังก์ชั่น myFunction() ( alert("hello"); ) myFunction() // เรียกใช้ฟังก์ชันหนึ่งครั้ง

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

คุณอาจเห็นฟังก์ชันที่กำหนดและเรียกใช้ในลักษณะที่แตกต่างกันเล็กน้อย จนถึงตอนนี้เราเพิ่งสร้างฟังก์ชั่นดังนี้:

ฟังก์ชั่น myFunction() ( alert("hello"); )

แต่คุณสามารถสร้างฟังก์ชันที่ไม่มีชื่อได้:

ฟังก์ชั่น() ( alert("hello"); )

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

Var myButton = document.querySelector("ปุ่ม"); myButton.onclick = function() ( alert("hello"); )

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

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

ตัวแปร myGreeting = function() ( alert("hello"); )

ตอนนี้สามารถเรียกใช้ฟังก์ชันนี้ได้โดยใช้:

MyGreeting();

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

Var anotherGreeting = function() ( alert("hello"); )

ขณะนี้สามารถเรียกใช้ฟังก์ชันนี้โดยใช้อย่างใดอย่างหนึ่ง

MyGreeting(); อีกคำทักทาย();

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

ฟังก์ชั่น myGreeting() ( alert("hello"); )

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

MyButton.onclick = function() ( alert("hello"); // ฉันสามารถใส่โค้ดได้มากเท่าไร // ข้างในนี้ได้ตามต้องการ )

พารามิเตอร์ฟังก์ชัน

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

หมายเหตุ : บางครั้งพารามิเตอร์เรียกว่าอาร์กิวเมนต์ คุณสมบัติ หรือแม้แต่แอตทริบิวต์

ตามตัวอย่าง ฟังก์ชัน Math.random() ในตัวของเบราว์เซอร์ไม่จำเป็นต้องใช้พารามิเตอร์ใดๆ เมื่อเรียกจะส่งกลับตัวเลขสุ่มระหว่าง 0 ถึง 1 เสมอ:

วาร์ myNumber = Math.random();

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

Var myText = "ฉันเป็นสตริง"; var newString = myText.replace("string", "ไส้กรอก");

หมายเหตุ : เมื่อคุณต้องการระบุพารามิเตอร์หลายตัว พารามิเตอร์เหล่านั้นจะถูกคั่นด้วยเครื่องหมายจุลภาค

ควรสังเกตว่าบางครั้งพารามิเตอร์ก็เป็นทางเลือก - คุณไม่จำเป็นต้องระบุพารามิเตอร์เหล่านั้น ถ้าคุณไม่ระบุ โดยทั่วไปฟังก์ชันจะใช้พฤติกรรมเริ่มต้นบางประเภท ตามตัวอย่าง พารามิเตอร์ของฟังก์ชัน array join() เป็นทางเลือก:

Var myArray = ["ฉัน", "ความรัก", "ช็อคโกแลต", "กบ"]; var madeAString = myArray.join(" "); // ส่งกลับ "ฉันรักกบช็อคโกแลต" var madeAString = myArray.join(); // ส่งกลับ "ฉันรักช็อคโกแลตกบ"

หากไม่มีพารามิเตอร์เพื่อระบุอักขระที่รวม/คั่น ระบบจะใช้ลูกน้ำเป็นค่าเริ่มต้น

ขอบเขตการทำงานและข้อขัดแย้ง

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

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

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

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

การทักทาย(); // first.js var name = "คริส"; ฟังก์ชั่น คำทักทาย() ( alert("Hello " + name + ": ยินดีต้อนรับสู่บริษัทของเรา"); ) // Second.js var name = "Zaptec"; ฟังก์ชั่น คำทักทาย() ( alert("บริษัทของเราชื่อ " + name + "."); )

ทั้งสองฟังก์ชันที่คุณต้องการเรียกใช้เรียกว่า Greeting() แต่คุณสามารถเข้าถึงฟังก์ชัน Greeting() ของไฟล์ Second.js ได้เท่านั้น โดยจะถูกนำไปใช้กับ HTML ในภายหลังในซอร์สโค้ด ดังนั้นตัวแปรและฟังก์ชันจึงเขียนทับ ที่อยู่ใน first.js

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

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

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

การเรียนรู้เชิงรุก: การเล่นอย่างมีขอบเขต

มาดูตัวอย่างจริงเพื่อสาธิตการกำหนดขอบเขต

  • ขั้นแรก สร้างสำเนาของตัวอย่าง function-scope.html ของเราในเครื่อง ประกอบด้วยฟังก์ชัน 2 รายการที่เรียกว่า a() และ b() และตัวแปร 3 ตัว ได้แก่ x , y และ z ซึ่ง 2 รายการถูกกำหนดไว้ภายในฟังก์ชัน และอีก 1 รายการอยู่ในขอบเขตส่วนกลาง นอกจากนี้ยังมีฟังก์ชันที่สามที่เรียกว่า output() ซึ่งรับพารามิเตอร์ตัวเดียวและส่งออกเป็นย่อหน้าบนเพจ
  • เปิดตัวอย่างในเบราว์เซอร์และในโปรแกรมแก้ไขข้อความของคุณ
  • เปิดคอนโซล JavaScript ในเครื่องมือสำหรับนักพัฒนาเบราว์เซอร์ของคุณ ในคอนโซล JavaScript ให้ป้อนคำสั่งต่อไปนี้: output(x);
  • คุณควรเห็นค่าของตัวแปร x เอาท์พุตไปที่หน้าจอ
  • ตอนนี้ลองป้อนข้อมูลต่อไปนี้ในเอาต์พุตคอนโซลของคุณ (y); เอาท์พุท(z);
  • ทั้งสองสิ่งนี้ควรส่งคืนข้อผิดพลาดตามบรรทัด "ReferenceError: y is not Defed" ทำไมเป็นเช่นนั้น? เนื่องจากขอบเขตฟังก์ชัน - y และ z ถูกล็อกอยู่ภายในฟังก์ชัน a() และ b() ดังนั้นเอาต์พุต () จึงไม่สามารถเข้าถึงได้เมื่อเรียกจากขอบเขตส่วนกลาง
  • อย่างไรก็ตาม แล้วเมื่อใดที่มันถูกเรียกจากภายในฟังก์ชันอื่น ลองแก้ไข a() และ b() เพื่อให้มีลักษณะดังนี้: function a() ( var y = 2; output(y); ) function b() ( var z = 3; output(z) บันทึกโค้ดและโหลดซ้ำในเบราว์เซอร์ของคุณ จากนั้นลองเรียกใช้ฟังก์ชัน a() และ b() จากคอนโซล JavaScript: a(); y และ z ค่าเอาต์พุตในหน้า วิธีนี้ใช้ได้ดีเนื่องจากฟังก์ชัน output() ถูกเรียกใช้ภายในฟังก์ชันอื่น ๆ - ในขอบเขตเดียวกันกับตัวแปรที่กำลังพิมพ์อยู่ ในแต่ละกรณีจะมีเอาต์พุต () เองจากทุกที่ตามที่กำหนดไว้ ในขอบเขตระดับโลก
  • ตอนนี้ลองอัปเดตโค้ดของคุณดังนี้: function a() ( var y = 2; output(x); ) function b() ( var z = 3; output(x); ) บันทึกและโหลดซ้ำอีกครั้ง และลองอีกครั้งใน คอนโซล JavaScript ของคุณ:
  • ก(); ข();
  • ทั้งการเรียก a() และ b() ควรส่งออกค่า x - 1 สิ่งเหล่านี้ทำงานได้ดีเพราะแม้ว่าการเรียก output() จะไม่อยู่ในขอบเขตเดียวกันกับที่ x กำหนดไว้ แต่ x ก็เป็นตัวแปรร่วมดังนั้นจึงพร้อมใช้งาน ภายในโค้ดทั้งหมดทุกที่

    สุดท้ายนี้ ลองอัปเดตโค้ดของคุณดังนี้: function a() ( var y = 2; output(z); ) function b() ( var z = 3; output(y); ) บันทึกและโหลดซ้ำอีกครั้ง และลองอีกครั้ง ในคอนโซล JavaScript ของคุณ: ก(); ข();ซึ่งมันจัดการและส่งกลับผลลัพธ์ ตัวอย่างเช่น ฟังก์ชัน y = 2 * x +5 ตรงนี้เราสามารถกำหนดให้ x = 3 และคำตอบจะเป็น y = 11 นี่คือตัวอย่างฟังก์ชันจากคณิตศาสตร์ มีฟังก์ชันที่คล้ายกันอย่างยิ่งใน JavaScript เฉพาะที่นี่เท่านั้นที่ฟังก์ชันนี้ไม่เพียงแต่คำนวณนิพจน์บางอย่างเท่านั้น แต่ยังเป็นอะไรก็ได้

    ขั้นแรกเรามาสร้างฟังก์ชั่นที่แสดงข้อความ "Hello" 3 ครั้งกันก่อน


    ฟังก์ชั่นสวัสดี() (
    alert("สวัสดี");
    alert("สวัสดี");
    alert("สวัสดี");
    }
    สวัสดี();

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

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

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

    ผลรวมฟังก์ชัน (x, y) (
    ผลรวม var = x + y;
    document.write(ผลรวม);
    }
    ผลรวม(5, 4);

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

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

    ผลรวมฟังก์ชัน(x, y) (
    ผลรวม var = x + y;
    จำนวนเงินที่ส่งคืน;
    }
    var z = ผลรวม(4, 5) + ผลรวม(1,-3);
    เอกสาร.write(z);

    ให้ความสนใจกับคีย์เวิร์ด return มันจะส่งคืนผลลัพธ์ (ในกรณีของเราคือผลรวมของตัวเลขสองตัว) ดังนั้น sum(4,5) จะส่งกลับ 9 เราเพิ่มตัวเลขนี้เข้ากับผลลัพธ์ของฟังก์ชัน sum(1, -3) นั่นคือ -2 เป็นผลให้เราได้ 7 จากนั้นเราจะพิมพ์ผลลัพธ์ในเบราว์เซอร์เท่านั้น

    ฉันหวังว่าคุณจะชื่นชมความสามารถของฟังก์ชันต่างๆ ดังนั้นการสร้างและใช้งานฟังก์ชันใน JavaScript จึงเป็นสิ่งจำเป็น และตอนนี้ฉันจะสรุปสิ่งสำคัญข้อหนึ่ง ซึ่งเป็นหลักการที่ต้องปฏิบัติตามเสมอ: โค้ดที่ซ้ำกันจะต้องแยกออกเป็นฟังก์ชันแยกต่างหาก หากคุณแสดง 5 บรรทัดเดียวกัน 20 ครั้ง (ตัวอย่าง) คุณจะต้องแยก 5 บรรทัดเหล่านี้ออกเป็นฟังก์ชันแยกกัน ดังนั้นแทนที่จะเขียน 100 บรรทัด (20 ครั้ง * 5 บรรทัด) ให้เขียนเพียง 20 บรรทัดและยิ่งเข้าใจได้มากขึ้น (ชื่อของฟังก์ชันนั้นง่ายกว่าโค้ด 5 บรรทัดมาก) ฉันอยากจะบอกว่าหากไม่ปฏิบัติตามกฎนี้ขนาดของโปรแกรมก็สามารถเพิ่มได้หลายสิบหรืออาจเป็นร้อยเท่า

    ฉันแนะนำให้คุณฝึกฝนและสร้างฟังก์ชั่นพื้นฐานทั้งหมด การดำเนินการทางคณิตศาสตร์(บวก ลบ คูณ หาร)

    เริ่มจากความจริงที่ว่า ภาษาจาวาสคริปต์รองรับแนวคิด OOP (Object Oriented Programming) แนวคิดนี้คือมีองค์ประกอบต่างๆ เช่น วัตถุ และวัตถุเหล่านี้มีคุณสมบัติและวิธีการ (ฟังก์ชัน) ที่หลากหลายที่ช่วยให้คุณสามารถจัดการพวกมันได้

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

    เมธอดก็เป็นฟังก์ชันเช่นกัน แต่มันก็เป็นของคลาสหรืออ็อบเจ็กต์บางตัวอยู่แล้ว

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

    นอกจากนี้ ในบทความก่อนหน้านี้ เราได้แนะนำวิธีการเอาท์พุต document.write() ซึ่งเป็นของอ็อบเจ็กต์ document

    ดังนั้นในการเขียนโปรแกรมจึงมีโอกาสที่สำคัญมาก ซึ่งก็คือคุณสามารถสร้างฟังก์ชันของคุณเองได้

    ไวยากรณ์ของฟังก์ชันมีลักษณะดังนี้:


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

    ฟังก์ชั่น writeText(text)( //เพิ่มข้อความในย่อหน้าแล้วแสดง document.write("

    "+ข้อความ+"

    "); ) //เรียกใช้ฟังก์ชันที่สร้างขึ้น writeText("Hello!");

    บันทึกเอกสารและเปิดในเบราว์เซอร์


    แสดงความคิดเห็น! เมื่อประกาศฟังก์ชัน ต้องมีเครื่องหมายปีกกาอยู่ ไม่ว่าจะมีโอเปอเรเตอร์กี่ตัวก็ตาม

    ฟังก์ชั่นที่จำเป็นในการเขียนโปรแกรมมีอะไรบ้าง?

    ข้อได้เปรียบหลักของการใช้ฟังก์ชันนี้คือการลดขนาดของซอร์สโค้ดสคริปต์

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

    //ประกาศสามอาร์เรย์ var arr1 = ; วาร์ arr2 = ["b", 5, 9.2, "h", 8, 2]; วาร์ arr2 = ; สำหรับ (var i = 0; i< arr1.length; i++){ document.write("

    องค์ประกอบอาร์เรย์ arr1 โดยมีดัชนี " + i + " เท่ากับ: "+ arr1[i] +"

    "); ) สำหรับ(var i = 0; i< arr2.length; i++){ document.write("

    องค์ประกอบอาร์เรย์ arr2 ที่มีดัชนี " + i + " เท่ากับ: "+ arr2[i] +"

    "); ) สำหรับ(var i = 0; i< arr3.length; i++){ document.write("

    องค์ประกอบอาร์เรย์ arr3 ที่มีดัชนี " + i + " เท่ากับ: "+ arr3[i] +"

    "); }

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

    ฟังก์ชัน printArr(arr)( for(var i = 0; i< arr.length; i++){ document.write("

    องค์ประกอบอาร์เรย์ที่มีดัชนี " + i + " เท่ากับ: "+ arr[i] +"

    "); ) ) // ประกาศสามอาร์เรย์ var arr1 = ; var arr2 = ["b", 5, 9.2, "h", 8, 2]; var arr2 = ; // เรียกใช้ฟังก์ชันที่สร้างขึ้นเพื่อวนซ้ำแต่ละอาร์เรย์ printArr (arr1); printArr (arr2);

    พารามิเตอร์ฟังก์ชัน

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

    มาสร้างฟังก์ชันแบบไม่มีพารามิเตอร์ที่พิมพ์วลี "Hello world" แบบคลาสสิกลงบนหน้าจอกันดีกว่า

    ฟังก์ชั่น helloWorld())( document.write("Hello World"); ) // เรียกใช้ฟังก์ชันโดยไม่มีพารามิเตอร์ helloWorld helloWorld();

    พารามิเตอร์ฟังก์ชันใดๆ สามารถมีค่าเริ่มต้นของตัวเองได้

    ซึ่งหมายความว่าหากเราไม่ส่งค่าใดๆ ไปยังพารามิเตอร์นี้เมื่อเรียกใช้ฟังก์ชัน มันจะใช้ค่าเริ่มต้น

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

    ฟังก์ชัน summa(number1, number2 = 4)( document.write("

    ผลรวมของตัวเลข " + ​​number1 + "(พารามิเตอร์แรก) และ" + number2 + "(พารามิเตอร์ที่สอง) เท่ากับ: " + (number1 + number2) + "

    "); ) // เรียกใช้ฟังก์ชันที่โดยค่าเริ่มต้นจะส่งออกผลลัพธ์ของการเพิ่มหมายเลขที่ส่งผ่านด้วยหมายเลข 4 summa(5); // ผลลัพธ์: 9 // ถ้าเราระบุพารามิเตอร์ตัวที่สองด้วย ฟังก์ชั่นจะแสดงผลลัพธ์ของการบวกตัวเลขจากพารามิเตอร์ทั้งสอง .summa(5, 20); // ผลลัพธ์: 25

    อาจเป็นไปได้ว่าภายในฟังก์ชันสามารถเรียกใช้ฟังก์ชันอื่นที่มีอยู่ได้ ตัวอย่างเช่น ลองเรียกใช้ฟังก์ชัน writeText() แรกที่เราสร้างขึ้นภายในฟังก์ชั่นก่อนหน้า

    สรุป() เราจะส่งต่อผลลัพธ์ของการเพิ่มตัวเลขให้กับฟังก์ชัน writeText() ในกรณีนี้ โค้ดสำหรับฟังก์ชัน summa() จะมีลักษณะดังนี้:

    ฟังก์ชั่น summa(number1, number2 = 4)( writeText(number1 + number2); ) //เรียกใช้ฟังก์ชัน summa summa(5); // ผลลัพธ์: 9 ผลรวม (5, 20); // ผลลัพธ์: 25

    ฟังก์ชั่นที่คืนค่าบางอย่าง

    จนถึงขณะนี้เรามีฟังก์ชั่นการเขียนที่แสดงผลลัพธ์บนหน้าจอทันที

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

    เพื่อให้เข้าใจสิ่งที่เรากำลังพูดถึงได้ดีขึ้น เรามาจำวิธีการต่างๆ เช่น prompt() และ ยืนยัน() วิธีการเหล่านี้คืนค่าที่ได้รับจากผู้ใช้จริง ๆ แทนที่จะแสดง

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

    ด้วยเหตุนี้ เราจึงได้คำว่า 'twix' เนื่องจากคำนี้เป็นองค์ประกอบสุดท้ายของอาร์เรย์ otherArr

    เมธอด alert() จะไม่ส่งคืนสิ่งใด นั่นคือถ้าเราพยายามแสดงตัวแปรที่มีประเภทมีผลของการเรียกเมธอด alert() เราจะเห็นค่า undefinition นี่เหมือนกับการพยายามแสดงค่าของตัวแปรว่าง

    ตัวอย่างเช่น ลองนำผลลัพธ์ของการเรียก alert() ครั้งล่าสุดจากตัวอย่างก่อนหน้า มาใส่ในตัวแปร resAlert และใช้ฟังก์ชัน writeText ที่เราสร้างขึ้นเพื่อลองพิมพ์ผลลัพธ์

    //แสดงองค์ประกอบสุดท้ายที่ได้รับของอาร์เรย์ var resAlert = alert(lastEl); การทดสอบ var; writeText(resAlert); //ไม่ได้กำหนด writeText(ทดสอบ); //ไม่ได้กำหนด

    อย่างที่คุณเห็นในทั้งสองกรณีเราได้รับค่าที่ไม่ได้กำหนด

    ตัวแปรโกลบอลและโลคัล

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

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

    ตัวแปรท้องถิ่นและระดับโลกไม่เกี่ยวข้องกันแต่อย่างใด


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

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

    เราเรียกฟังก์ชัน other() และถ้าเราพยายามแสดงค่าของตัวแปร x เราจะเห็นผลลัพธ์เป็นเลข 4

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

    วาร์ x = 8; เพิ่มฟังก์ชัน() ( x++; ) //เรียกฟังก์ชันเพิ่ม() เพิ่มค่า(); การแจ้งเตือน(x); //ผลลัพธ์: 9

    หากเราไม่ต้องการให้ตัวแปรส่วนกลางเปลี่ยนแปลง เราต้องประกาศตัวแปรท้องถิ่น (อาจมีชื่อเดียวกับตัวแปรส่วนกลาง) และการดำเนินการทั้งหมดจะดำเนินการกับตัวแปรนั้น

    วาร์ ก = 100; function func())( var g = 14; g *= 2; // นี่เหมือนกับ g = g * 2 alert(g); // ผลลัพธ์: 28 ) // เรียกใช้ฟังก์ชัน ฟังก์ชั่น(); alert(g);//ผลลัพธ์: 100

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

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

    งาน
  • สร้างฟังก์ชันที่รับตัวเลขสองตัวเป็นพารามิเตอร์ และส่งกลับผลลัพธ์ของการคูณตัวเลขเหล่านั้น
  • พิมพ์ผลลัพธ์
  • 24 พฤษภาคม 2554 เวลา 01:13 น. ห้าวิธีในการเรียกใช้ฟังก์ชัน
    • จาวาสคริปต์
    • การแปล

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

    ในช่วงแรกของการเรียนรู้ JavaScript ผู้เริ่มต้นมักจะคิดว่าฟังก์ชันในนั้นทำงานในลักษณะเดียวกับใน C# แต่กลไกในการเรียกใช้ฟังก์ชันใน JavaScript มีความแตกต่างที่สำคัญหลายประการ และการเพิกเฉยต่อกลไกเหล่านี้อาจทำให้เกิดข้อผิดพลาดซึ่งหาไม่ได้ง่าย

    เรามาเขียนฟังก์ชันง่ายๆ ที่ส่งคืนอาร์เรย์ขององค์ประกอบ 3 รายการ ได้แก่ ค่าปัจจุบันและอาร์กิวเมนต์ทั้งสองที่ส่งไปยังฟังก์ชัน
    ฟังก์ชั่น makeArray(arg1, arg2)( return [ this, arg1, arg2 ]; )

    วิธีที่พบบ่อยที่สุด: การโทรทั่วโลก ผู้เริ่มต้นมักจะประกาศฟังก์ชันตามที่แสดงในตัวอย่างด้านบน การเรียกใช้ฟังก์ชันนี้เป็นเรื่องง่าย:
    makeArray("หนึ่ง", "สอง"); // => [ หน้าต่าง "หนึ่ง", "สอง" ]
    รอ. วัตถุหน้าต่างมาจากไหน? ทำไมมันถึงเท่ากับหน้าต่าง?

    ใน JavaScript ไม่ว่าสคริปต์จะถูกเรียกใช้งานในเบราว์เซอร์หรือในสภาพแวดล้อมอื่นก็ตาม สคริปต์นั้นจะถูกกำหนดไว้เสมอ วัตถุระดับโลก- รหัสใดๆ ในสคริปต์ของเราที่ไม่ได้ "ผูกมัด" กับสิ่งใดๆ (นั่นคือ ภายนอกการประกาศวัตถุ) จริงๆ แล้วอยู่ในบริบทของวัตถุส่วนกลาง ในกรณีของเรา makeArray ไม่ใช่แค่ฟังก์ชัน "การเดิน" ด้วยตัวมันเอง ในความเป็นจริง makeArray เป็นวิธีการของหน้าต่างอ็อบเจ็กต์โกลบอล (ในกรณีของการเรียกใช้โค้ดในเบราว์เซอร์) ง่ายที่จะพิสูจน์:
    การแจ้งเตือน (ประเภทของ window.methodThatDoesntExist); // => การแจ้งเตือนที่ไม่ได้กำหนด (typeof window.makeArray); // => ฟังก์ชั่น
    นั่นคือการเรียก makeArray("one", "two"); เทียบเท่ากับการเรียก window.makeArray("one", "two"); -

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

    กฎการเรียกใช้ฟังก์ชัน #1: หากเรียกใช้ฟังก์ชันโดยตรงโดยไม่ระบุวัตถุ (เช่น myFunction()) ค่าของสิ่งนี้จะเป็นวัตถุส่วนกลาง (หน้าต่างหากโค้ดถูกเรียกใช้งานในเบราว์เซอร์)

    การเรียกเมธอด มาสร้างออบเจ็กต์อย่างง่ายและทำให้ makeArray เป็นเมธอดของมันกันดีกว่า เรามาประกาศวัตถุโดยใช้สัญกรณ์ตามตัวอักษรแล้วเรียกวิธีการของเรา:
    // สร้างวัตถุ var arrayMaker = ( someProperty: "บางค่า", make: makeArray ); // เรียกใช้เมธอด make() arrayMaker.make("one", "two"); // => [ arrayMaker, "one", "two" ] // ไวยากรณ์ทางเลือก, ใช้วงเล็บเหลี่ยม arrayMaker["make"]("one", "two"); // => [ arrayMaker, "หนึ่ง", "สอง" ]
    คุณเห็นความแตกต่างหรือไม่? ค่าในกรณีนี้คือตัววัตถุเอง ทำไมไม่ window เหมือนในกรณีก่อนหน้านี้เนื่องจากการประกาศฟังก์ชั่นไม่มีการเปลี่ยนแปลง? เคล็ดลับคือวิธีการส่งผ่านฟังก์ชันต่างๆ ใน ​​JavaScript ฟังก์ชันเป็นประเภท JavaScript มาตรฐานที่เป็นวัตถุจริงๆ และเช่นเดียวกับวัตถุอื่นๆ ฟังก์ชันสามารถส่งผ่านและคัดลอกได้ ในกรณีนี้ เราได้คัดลอกฟังก์ชันทั้งหมดแล้ว รวมถึงรายการอาร์กิวเมนต์และเนื้อหา และกำหนดวัตถุผลลัพธ์ให้กับคุณสมบัติ make ของวัตถุ arrayMaker นี่เทียบเท่ากับการประกาศเช่นนี้:
    var arrayMaker = ( someProperty: "ค่าบางอย่าง"; make: function (arg1, arg2) ( return [ this, arg1, arg2]; ) );
    กฎการเรียกใช้ฟังก์ชัน #2: ในฟังก์ชันที่เรียกว่าโดยใช้ไวยากรณ์การเรียกเมธอด เช่น obj.myFunction() หรือ obj["myFunction"]() สิ่งนี้จะมีค่า obj

    ความเข้าใจผิดเกี่ยวกับหลักการง่ายๆ โดยทั่วไปนี้มักนำไปสู่ข้อผิดพลาดเมื่อประมวลผลเหตุการณ์:
    function buttonClicked())( var text = (this === window) ? "window" : this.id; alert(text); ) var button1 = document.getElementById("btn1"); var button2 = document.getElementById("btn2"); button1.onclick = ปุ่มคลิก; button2.onclick = ฟังก์ชั่น())( ปุ่มคลิก(); );
    การคลิกปุ่มแรกจะแสดงข้อความ "btn1"เพราะในกรณีนี้ เรากำลังเรียกใช้ฟังก์ชันเป็นเมธอด และสิ่งนี้ภายในฟังก์ชันจะได้รับค่าของอ็อบเจ็กต์ที่เป็นของเมธอดนี้ การคลิกปุ่มที่สองจะให้ "หน้าต่าง"เพราะในกรณีนี้เรากำลังเรียก buttonClicked โดยตรง (เช่น ไม่เหมือนกับ obj.buttonClicked()) สิ่งเดียวกันนี้จะเกิดขึ้นเมื่อเรากำหนดตัวจัดการเหตุการณ์ให้กับแท็กองค์ประกอบ เช่นเดียวกับในกรณีของปุ่มที่สาม การคลิกปุ่มที่สามจะแสดงข้อความเดียวกันกับปุ่มที่สอง

    เมื่อใช้ไลบรารีเช่น jQuery คุณไม่จำเป็นต้องคิดถึงเรื่องนี้ jQuery จะดูแลเขียนค่านี้ใหม่ในตัวจัดการเหตุการณ์เพื่อให้ค่านี้เป็นองค์ประกอบที่ทำให้เกิดเหตุการณ์:
    // ใช้ jQuery $("#btn1").click(function() ( alert(this.id); // jQuery จะตรวจสอบให้แน่ใจว่า "นี่คือปุ่ม" ));
    อะไร วิธี jQueryเป็นไปได้ไหมที่จะเปลี่ยนค่าของสิ่งนี้? อ่านด้านล่าง

    อีกสองวิธี: Apply() และ call() เป็นตรรกะที่ยิ่งคุณใช้ฟังก์ชันบ่อยเท่าไร คุณก็ยิ่งต้องส่งผ่านและเรียกฟังก์ชันเหล่านั้นในบริบทที่แตกต่างกันบ่อยขึ้นเท่านั้น บ่อยครั้งมีความจำเป็นต้องแทนที่ค่าของสิ่งนี้ หากคุณจำได้ว่าฟังก์ชันใน JavaScript นั้นเป็นวัตถุ ในทางปฏิบัติ หมายความว่าฟังก์ชันมีวิธีการที่กำหนดไว้ล่วงหน้า Apply() และ call() เป็นสองรายการ อนุญาตให้คุณแทนที่ค่านี้:
    var car = ( ปี: 2008 รุ่น: "Dodge Bailout" ); makeArray.apply (รถยนต์, [ "หนึ่ง", "สอง" ]); // => [ รถยนต์ "หนึ่ง", "สอง" ] makeArray.call(รถยนต์ "หนึ่ง", "สอง"); // => [ รถยนต์ "หนึ่ง", "สอง" ]
    ทั้งสองวิธีนี้มีความคล้ายคลึงกันมาก พารามิเตอร์แรกจะแทนที่สิ่งนี้ ความแตกต่างระหว่างพวกเขาอยู่ในอาร์กิวเมนต์ที่ตามมา: Function.apply() ยอมรับอาร์เรย์ของค่าที่จะถูกส่งไปยังฟังก์ชัน ในขณะที่ Function.call() ยอมรับอาร์กิวเมนต์แยกกัน ในทางปฏิบัติ ผมว่า Apply() สะดวกกว่านะ

    กฎการเรียกใช้ฟังก์ชัน #3: หากคุณต้องการแทนที่ค่านี้โดยไม่คัดลอกฟังก์ชันไปยังอ็อบเจ็กต์อื่น คุณสามารถใช้ myFunction.apply(obj) หรือ myFunction.call(obj)

    ฉันจะไม่ลงรายละเอียดเกี่ยวกับการประกาศประเภทที่กำหนดเองใน JavaScript แต่ฉันคิดว่าสิ่งสำคัญคือต้องเตือนคุณว่าไม่มีคลาสใน JavaScript และประเภทที่กำหนดเองใดๆ ก็ตามจำเป็นต้องมีตัวสร้าง นอกจากนี้ เป็นการดีกว่าที่จะประกาศวิธีการประเภทที่กำหนดเองโดยใช้ต้นแบบ ซึ่งเป็นคุณสมบัติของฟังก์ชันตัวสร้าง มาสร้างประเภทของเราเอง:
    // ประกาศฟังก์ชันคอนสตรัคเตอร์ ArrayMaker(arg1, arg2) ( this.someProperty = "no Matter"; this.theArray = [ this, arg1, arg2 ]; ) // ประกาศวิธีการ ArrayMaker.prototype = ( someMethod: function () ( alert( "ถูกเรียกโดย someMethod"); getArray: function () ( return this.theArray; ) ); var am = new ArrayMaker("หนึ่ง", "สอง"); var other = new ArrayMaker("ครั้งแรก", "วินาที"); am.getArray(); // => [ เช้า "หนึ่ง", "สอง" ]
    สิ่งสำคัญในตัวอย่างนี้คือการมีโอเปอเรเตอร์ใหม่อยู่ก่อนการเรียกใช้ฟังก์ชัน หากไม่เป็นเช่นนั้น มันจะเป็นการโทรทั่วโลก และคุณสมบัติที่สร้างขึ้นในตัวสร้างจะเป็นของวัตถุโกลบอล เราไม่ต้องการสิ่งนั้น นอกจากนี้ตัวสร้างมักจะไม่ส่งคืนค่าอย่างชัดเจน หากไม่มีโอเปอเรเตอร์ใหม่ Constructor จะส่งคืน undefinition โดยจะส่งคืนสิ่งนี้ ถือเป็นรูปแบบที่ดีในการตั้งชื่อตัวสร้างด้วยตัวพิมพ์ใหญ่ สิ่งนี้จะเตือนคุณถึงความจำเป็นในการมีโอเปอเรเตอร์ใหม่

    มิฉะนั้น โค้ดภายใน Constructor อาจจะคล้ายกับโค้ดที่คุณจะเขียนในภาษาอื่น ค่าในกรณีนี้คือออบเจ็กต์ใหม่ที่คุณกำลังสร้าง

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

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

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

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

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

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

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

    การประกาศฟังก์ชัน ฟังก์ชันในรูปแบบ "คำสั่งการประกาศฟังก์ชัน"

    ประกาศฟังก์ชัน ( นิยามฟังก์ชัน, หรือ ประกาศฟังก์ชัน, หรือ คำสั่งฟังก์ชัน) ประกอบด้วยคีย์เวิร์ดของฟังก์ชันและส่วนต่างๆ ดังต่อไปนี้:

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

    ตัวอย่างเช่น รหัสต่อไปนี้ประกาศฟังก์ชันแบบง่ายชื่อ square:

    ฟังก์ชั่น สแควร์(หมายเลข) ( หมายเลขส่งคืน * หมายเลข; )

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

    กลับหมายเลข * หมายเลข;

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

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

    ฟังก์ชั่น myFunc(theObject) ( theObject.make = "Toyota"; ) var mycar = (ยี่ห้อ: "Honda", รุ่น: "Accord", ปี: 1998); วาร์ x, y; x = mycar.make; // x รับค่า "Honda" myFunc(mycar); y = mycar.make; // y รับค่า "โตโยต้า" // (คุณสมบัติถูกเปลี่ยนโดยฟังก์ชัน)

    หน้าที่ของรูปแบบ "นิพจน์นิยามฟังก์ชัน"

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

    Var square = function(number) ( return number * number; ); var x = สี่เหลี่ยมจัตุรัส (4); // x ได้รับค่า 16

    อย่างไรก็ตาม สามารถกำหนดชื่อให้เรียกตัวเองภายในฟังก์ชันเองและสำหรับดีบักเกอร์ ( ดีบักเกอร์) เพื่อระบุฟังก์ชันในการติดตามสแต็ก ( ร่องรอยสแต็ก- "ติดตาม" - "ติดตาม" / "สำนักพิมพ์")

    Var factorial = ฟังก์ชัน fac(n) ( return n< 2 ? 1: n * fac(n - 1); }; console.log(factorial(3));

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

    Function map(f, a) ( var result = , // สร้าง Array ใหม่ i; for (i = 0; i != a.length; i++) result[i] = f(a[i]); return result ; )

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

    Function map(f, a) ( var result = ; // สร้าง Array ใหม่ var i; // ประกาศตัวแปรสำหรับ (i = 0; i != a.length; i++) result[i] = f(a[i ]); ส่งคืนผลลัพธ์; ) var f = function(x) ( ส่งคืน x * x * x; ) var ตัวเลข = ; var cube = แผนที่ (f, ตัวเลข); console.log(คิวบ์);

    ฟังก์ชันส่งคืน: .

    ใน JavaScript สามารถประกาศฟังก์ชันโดยมีเงื่อนไขได้ ตัวอย่างเช่น ฟังก์ชันต่อไปนี้จะถูกกำหนดให้กับตัวแปร myFunc หาก num เป็น 0 เท่านั้น:

    วาร์ myFunc; ถ้า (num === 0) ( myFunc = function(theObject) ( theObject.make = "Toyota"; ) )

    นอกเหนือจากการประกาศฟังก์ชันที่อธิบายไว้ที่นี่ คุณยังสามารถใช้ตัวสร้างฟังก์ชันเพื่อสร้างฟังก์ชันจากสตริง ณ รันไทม์ ( รันไทม์), ชอบ .

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

    การเรียกใช้ฟังก์ชัน

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

    สี่เหลี่ยม(5);

    คำสั่งนี้เรียกใช้ฟังก์ชันที่มีอาร์กิวเมนต์ 5 ฟังก์ชันเรียกคำสั่งและส่งกลับค่า 25

    ฟังก์ชั่นสามารถอยู่ในขอบเขตเมื่อมีการกำหนดไว้แล้ว แต่ฟังก์ชั่นของแบบฟอร์ม "คำสั่งการประกาศฟังก์ชั่น" สามารถยกขึ้นได้ ( เลี้ยง - ยก) เช่นเดียวกับในตัวอย่างนี้:

    Console.log (สี่เหลี่ยม (5)); /* ... */ ฟังก์ชั่น สแควร์(n) ( return n * n; )

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

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

    Console.log (สี่เหลี่ยมจัตุรัส); // ยกกำลังสองด้วยค่าที่ไม่ได้กำหนด console.log(สี่เหลี่ยม(5)); // TypeError: square ไม่ใช่ฟังก์ชัน var square = function(n) ( return n * n; )

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

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

    ฟังก์ชัน factorial(n) ( if ((n === 0) || (n === 1)) return 1; else return (n * factorial(n - 1)); )

    จากนั้นคุณสามารถคำนวณแฟกทอเรียลจาก 1 ถึง 5 ได้ดังนี้:

    วาร์ ก, ข, ค, ง, อี; ก = แฟกทอเรียล (1); // a รับค่า 1 b = แฟกทอเรียล (2); // b รับค่า 2 c = แฟกทอเรียล (3); // c รับค่า 6 d = แฟกทอเรียล (4); // d รับค่า 24 e = factorial(5); //e รับค่า 120

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

    ขอบเขตของฟังก์ชัน

    (ขอบเขตฟังก์ชัน)

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

    // ตัวแปรต่อไปนี้ถูกประกาศในขอบเขตสากล var num1 = 20, num2 = 3, name = "Chamahk"; // ฟังก์ชันนี้ถูกประกาศในฟังก์ชันขอบเขตสากล multiply() ( return num1 * num2; ) multiply(); // จะส่งกลับ 60 // ตัวอย่างของฟังก์ชันที่ซ้อนกัน function getScore() ( var num1 = 2, num2 = 3; function add() ( return name + "scored" + (num1 + num2); ) return add(); ) รับคะแนน( ); // จะกลับมา "ชะมะคะแนน 5"

    ขอบเขตและสแต็กฟังก์ชัน

    (สแต็กฟังก์ชัน)

    การเรียกซ้ำ

    ฟังก์ชั่นสามารถเรียกตัวเองได้ สามวิธีในการเรียกสิ่งนี้:

  • ตามชื่อฟังก์ชัน
  • โดยตัวแปรที่อ้างถึงฟังก์ชัน
  • ตัวอย่างเช่น พิจารณาฟังก์ชันต่อไปนี้:

    Var foo = function bar() ( // คำสั่งไปที่นี่ );

    ภายในฟังก์ชัน ( ฟังก์ชั่นร่างกาย) การโทรต่อไปนี้ทั้งหมดเทียบเท่ากัน:

  • บาร์()
  • อาร์กิวเมนต์.callee()
  • ฟู()
  • ฟังก์ชันที่เรียกตัวเองเรียกว่า ฟังก์ชันแบบเรียกซ้ำ (ฟังก์ชันแบบเรียกซ้ำ- ปรากฎว่าการเรียกซ้ำนั้นคล้ายกับการวนซ้ำ ( วนซ้ำ- ทั้งสองเรียกโค้ดหลายครั้ง และทั้งคู่ต้องมีเงื่อนไข (เพื่อหลีกเลี่ยง วนซ้ำไม่รู้จบหรือการเรียกซ้ำแบบไม่มีที่สิ้นสุด) ตัวอย่างเช่น วงต่อไปนี้:

    วาร์ x = 0; ในขณะที่(x< 10) { // "x < 10" - это условие для цикла // do stuff x++; }

    สามารถเปลี่ยนเป็นฟังก์ชันแบบเรียกซ้ำและเรียกใช้ฟังก์ชันนี้ได้:

    Function loop(x) ( if (x >= 10) // "x >= 10" เป็นเงื่อนไขสำหรับการสิ้นสุดการดำเนินการ (เหมือนกับ "!(x< 10)") return; // делать что-то loop(x + 1); // рекурсионный вызов } loop(0);

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

    ฟังก์ชั่น walkTree(node) ( if (node ​​​​== null) // return; // ทำบางสิ่งกับองค์ประกอบสำหรับ (var i = 0; i< node.childNodes.length; i++) { walkTree(node.childNodes[i]); } }

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

    นอกจากนี้ยังเป็นไปได้ที่จะเปลี่ยนอัลกอริธึมแบบเรียกซ้ำบางส่วนให้เป็นแบบไม่เรียกซ้ำ แต่บ่อยครั้งที่ตรรกะนั้นซับซ้อนมากและจำเป็นต้องใช้สแต็ก ( สแต็ค- ในความเป็นจริง การเรียกซ้ำใช้ stach: function stack

    พฤติกรรมของสแต็ก" สามารถดูได้ในตัวอย่างต่อไปนี้:

    ฟังก์ชั่น foo(i) ( ถ้า (i< 0) return; console.log("begin: " + i); foo(i - 1); console.log("end: " + i); } foo(3); // Output: // begin: 3 // begin: 2 // begin: 1 // begin: 0 // end: 0 // end: 1 // end: 2 // end: 3

    ฟังก์ชั่นและการปิดที่ซ้อนกัน

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

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

    สรุป:

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

    ตัวอย่างต่อไปนี้แสดงฟังก์ชันที่ซ้อนกัน:

    ฟังก์ชัน addSquares(a, b) ( function square(x) ( return x * x; ) return square(a) + square(b); ) a = addSquares(2, 3); // ส่งคืน 13 b = addSquares(3, 4); // ส่งคืน 25 c = addSquares(4, 5); // คืนค่า 41

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

    ฟังก์ชั่นภายนอก(x) ( ฟังก์ชั่นภายใน(y) ( กลับ x + y; ) กลับภายใน; ) fn_inside = ภายนอก(3); // ลองคิดดู: ขอฟังก์ชันให้ฉันหน่อย // ที่ผ่าน 3 result = fn_inside(5); // ส่งกลับ 8 result1 = ภายนอก (3) (5); // ส่งคืน 8

    การบันทึกตัวแปร

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

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

    ฟังก์ชันที่ซ้อนกันแบบทวีคูณ

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

    ลองพิจารณาตัวอย่างต่อไปนี้:

    ฟังก์ชัน A(x) ( ฟังก์ชั่น B(y) ( ฟังก์ชั่น C(z) ( console.log(x + y + z); ) C(3); ) B(2); ) A(1); // คอนโซลจะแสดง 6 (1 + 2 + 3)

    ในตัวอย่างนี้ C มีสิทธิ์เข้าถึง y ของฟังก์ชัน B และ x ของฟังก์ชัน A สิ่งนี้เกิดขึ้นเพราะ:

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

    ข้อขัดแย้งของชื่อ

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

    ฟังก์ชั่นภายนอก() ( var x = 5; ฟังก์ชั่นภายใน(x) ( return x * 2; ) กลับภายใน; ) ภายนอก())(10); // คืนค่า 20 แทนที่จะเป็น 10

    ความขัดแย้งของชื่อเกิดขึ้นในคำสั่ง return x * 2 ระหว่างพารามิเตอร์ x ของฟังก์ชันภายในและตัวแปร x ของฟังก์ชันภายนอก ห่วงโซ่ขอบเขตที่นี่จะเป็นดังนี้: ( inside ==> ภายนอก ==> global object ( วัตถุระดับโลก- ดังนั้น x ของฟังก์ชันภายในจะมีลำดับความสำคัญมากกว่าฟังก์ชันภายนอก และเราจะถูกส่งกลับ 20 (= 10 * 2) แทนที่จะเป็น 10 (= 5 * 2)

    การปิด

    (ปิด)

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

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

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

    การปิดจะถูกสร้างขึ้นเมื่อฟังก์ชันที่ซ้อนกันสามารถเข้าถึงได้ในบางขอบเขตนอกฟังก์ชันภายนอก

    Var pet = function(name) ( // ฟังก์ชันภายนอกประกาศตัวแปร "name" var getName = function() ( return name; // ฟังก์ชันที่ซ้อนกันสามารถเข้าถึง "name" ของฟังก์ชันภายนอก ) return getName; / / ส่งคืนฟังก์ชันที่ซ้อนกัน ดังนั้นจึงรักษาการเข้าถึง // ไปยังขอบเขตอื่น) myPet = pet("Vivie"); myPet(); // "Vivie" ถูกส่งคืน // เพราะ แม้หลังจากดำเนินการฟังก์ชันภายนอกแล้ว // ชื่อจะถูกเก็บรักษาไว้สำหรับฟังก์ชันที่ซ้อนกัน

    ตัวอย่างที่ซับซ้อนยิ่งขึ้นแสดงไว้ด้านล่าง วัตถุที่มีวิธีการจัดการกับฟังก์ชันที่ซ้อนกันโดยฟังก์ชันภายนอกสามารถส่งคืนได้ ( กลับ).

    Var createPet = function(name) ( var sex; return ( setName: function(newName) ( name = newName; ), getName: function() ( return name; ), getSex: function() ( return sex; ), setSex: ฟังก์ชั่น(newSex) ( if(typeof newSex === "string" && (newSex.toLowerCase() === "male" || newSex.toLowerCase() === "Female")) ( sex = newSex; ) ) ) ) var pet = createPet("Vivie"); pet.getName(); // Vivie pet.setName("โอลิเวอร์"); pet.setSex("ชาย"); สัตว์เลี้ยง.getSex(); // ตัวผู้ pet.getName(); //โอลิเวอร์

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

    Var getCode = (function() ( var apiCode = "0]Eal(eh&2"; // โค้ดเราไม่ต้องการให้บุคคลภายนอกสามารถแก้ไขได้... return function() ( return apiCode; ); )()) ; getCode(); // ส่งคืน apiCode

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

    Var createPet = function(name) ( // ฟังก์ชั่นภายนอกกำหนดตัวแปรชื่อ "name" return ( setName: function(name) ( // ฟังก์ชั่นที่แนบมายังกำหนดตัวแปรชื่อ "name" อีกด้วย name = name; // เราจะเข้าถึง "ชื่อ" ที่กำหนดโดยฟังก์ชันภายนอกได้อย่างไร

    การใช้วัตถุอาร์กิวเมนต์

    วัตถุอาร์กิวเมนต์ของฟังก์ชันคืออาร์เรย์เทียม ภายในฟังก์ชัน คุณสามารถอ้างถึงข้อโต้แย้งดังนี้:

    อาร์กิวเมนต์[i]

    โดยที่ i คือเลขลำดับของอาร์กิวเมนต์ โดยเริ่มจาก 0 อาร์กิวเมนต์แรกที่ส่งไปยังฟังก์ชันจะระบุเป็นอาร์กิวเมนต์ และรับจำนวนอาร์กิวเมนต์ทั้งหมด - arguments.length

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

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

    ฟังก์ชั่น myConcat(separator) ( var result = ""; var i; // วนซ้ำอาร์กิวเมนต์สำหรับ (i = 1; i< arguments.length; i++) { result += arguments[i] + separator; } return result; }

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

    // ส่งกลับ "แดง, ส้ม, น้ำเงิน, " myConcat(", ", "red", "orange", "blue"); // ส่งคืน "elephant; giraffe; lion; cheetah; " myConcat("; ", "elephant", "giraffe", "lion", "cheetah"); // ส่งคืน "sage.basil.oregano.pepper.parsley" myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");

    เพราะ อาร์กิวเมนต์เป็นอาร์เรย์เทียม ซึ่งวิธีการอาร์เรย์บางวิธีจะนำไปใช้กับมัน เช่น สำหรับ .. in

    ฟังก์ชั่น func() ( สำหรับ (ค่าในอาร์กิวเมนต์)( console.log(value); ) ) func(1, 2, 3); // 1 // 2 // 3

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

    พารามิเตอร์ที่เหลือ

    การใช้ฟังก์ชันลูกศรได้รับอิทธิพลจากปัจจัย 2 ประการ ได้แก่ ฟังก์ชันที่สั้นกว่าและศัพท์นี้

    ฟังก์ชั่นที่สั้นกว่า

    รูปแบบการทำงานบางอย่างสนับสนุนการใช้ฟังก์ชันที่สั้นกว่า เปรียบเทียบ:

    Var a = ["ไฮโดรเจน", "ฮีเลียม", "ลิเธียม", "เบริลเลียม" ]; var a2 = a.map(function(s) ( return s.length; )); console.log(a2); // บันทึก var a3 = a.map(s => s.length); console.log(a3); // บันทึก

    คำศัพท์อันนี้

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

    Function Person() ( // ตัวสร้าง Person() กำหนด `this` ด้วยตัวเอง this.age = 0; setInterval(function growUp() ( // หากไม่มีโหมดเข้มงวด ฟังก์ชัน growUp() จะกำหนด `this` // เป็น วัตถุโกลบอล ซึ่งแตกต่างจาก `this` // กำหนดโดยตัวสร้าง Person() this.age++; ) var p = new Person();

    ECMAScript 3/5 แก้ไขปัญหานี้โดยการกำหนดค่าให้กับตัวแปรที่สามารถวนซ้ำได้

    Function Person() ( var self = this; // บางคนเลือก `that` แทนที่จะเป็น `self` // เลือกอันหนึ่งแล้วทำให้สอดคล้องกัน self.age = 0; setInterval(function growUp() ( // การเรียกกลับไปยัง ตัวแปร `self` ซึ่ง // ค่าเป็นวัตถุที่คาดหวัง self.age++), 1,000);

    ดูเพิ่มเติมที่ฟังก์ชันในการอ้างอิง JavaScript สำหรับข้อมูลเพิ่มเติมเกี่ยวกับฟังก์ชันเป็นอ็อบเจ็กต์



    มีคำถามอะไรไหม?

    แจ้งการพิมพ์ผิด

    ข้อความที่จะส่งถึงบรรณาธิการของเรา: