1. การปิดคืออะไร
การปิดเป็นฟังก์ชั่นที่ได้รับอนุญาตให้เข้าถึงตัวแปรในขอบเขตฟังก์ชันอื่น
พูดง่ายๆ JavaScript อนุญาตให้ใช้ฟังก์ชั่นภายใน - นั่นคือคำจำกัดความของฟังก์ชั่นและการแสดงออกของฟังก์ชั่นอยู่ในฟังก์ชันของฟังก์ชั่นอื่น ยิ่งไปกว่านั้นฟังก์ชั่นภายในเหล่านี้สามารถเข้าถึงตัวแปรท้องถิ่นพารามิเตอร์และฟังก์ชั่นภายในอื่น ๆ ที่ประกาศในฟังก์ชั่นภายนอกที่พวกเขาอาศัยอยู่ เมื่อหนึ่งในฟังก์ชั่นภายในเหล่านี้เรียกว่านอกฟังก์ชั่นภายนอกที่มีอยู่การปิดจะเกิดขึ้น
2. ขอบเขตของตัวแปร
เพื่อให้เข้าใจการปิดคุณต้องเข้าใจขอบเขตของตัวแปรก่อน
มีเพียงสองประเภทของตัวแปร: ตัวแปรทั่วโลกและตัวแปรท้องถิ่น
คุณสมบัติพิเศษของภาษา JavaScript คือตัวแปรทั่วโลกสามารถอ่านได้โดยตรงภายในฟังก์ชั่น
ตัวแปรของฟังก์ชั่นภายนอกสามารถเข้าถึงได้ในฟังก์ชั่นภายในเนื่องจากห่วงโซ่ขอบเขตของฟังก์ชั่นภายในมีขอบเขตของฟังก์ชันภายนอก
นอกจากนี้ยังสามารถเข้าใจได้ว่า: ช่วงของการกระทำของฟังก์ชั่นภายในแผ่กระจายไปตามช่วงของการกระทำของฟังก์ชั่นภายนอก
var n = 999; ฟังก์ชั่น f1 () {แจ้งเตือน (n);} f1 (); // 999ในทางกลับกันตัวแปรท้องถิ่นภายในฟังก์ชั่นจะไม่อ่านนอกฟังก์ชั่นตามธรรมชาติ
ฟังก์ชั่น f1 () {var n = 999;} การแจ้งเตือน (n); // ข้อผิดพลาดมีสถานที่ที่ควรทราบที่นี่ เมื่อประกาศตัวแปรภายในคุณต้องใช้คำสั่ง VAR ถ้าไม่คุณก็ประกาศตัวแปรทั่วโลก!
ฟังก์ชั่น f1 () {n = 999;} f1 (); แจ้งเตือน (n); // 9993. หลายวิธีในการเขียนและใช้การปิด
3.1. เพิ่มคุณสมบัติบางอย่างลงในฟังก์ชัน
วงกลมฟังก์ชัน (r) {this.r = r; } circle.pi = 3.14159; circle.prototype.area = function () {return circle.pi * this.r * this.r; } var c = วงกลมใหม่ (1.0); การแจ้งเตือน (c.area ()); //3.141593.2. ประกาศตัวแปรและกำหนดฟังก์ชันให้กับตัวแปรเป็นค่า
var circle = function () {var obj = วัตถุใหม่ (); obj.pi = 3.14159; obj.area = function (r) {return this.pi * r * r; } return obj; } var c = วงกลมใหม่ (); การแจ้งเตือน (C.AREA (1.0)); //3.141593.3. วิธีนี้ใช้บ่อยขึ้นและสะดวกที่สุด var obj = {} คือการประกาศวัตถุที่ว่างเปล่า
var circle = {"pi": 3.14159, "พื้นที่": ฟังก์ชัน (r) {return this.pi * r * r; - Alert (circle.area (1.0)); // 3.141594. ฟังก์ชั่นหลักของการปิด
การปิดสามารถใช้ในหลายสถานที่ มันมีการใช้งานที่ใหญ่ที่สุดสองครั้ง: หนึ่งคือตัวแปรภายในฟังก์ชั่นสามารถอ่านได้ตามที่กล่าวไว้ข้างต้นและอื่น ๆ คือค่าของตัวแปรเหล่านี้จะถูกเก็บไว้ในหน่วยความจำเสมอ
4.1. วิธีอ่านตัวแปรท้องถิ่นจากภายนอก?
ด้วยเหตุผลต่าง ๆ บางครั้งเราจำเป็นต้องได้รับตัวแปรท้องถิ่นภายในฟังก์ชั่น อย่างไรก็ตามดังที่ได้กล่าวไว้ก่อนหน้านี้ภายใต้สถานการณ์ปกติสิ่งนี้ไม่สามารถทำได้และสามารถทำได้ผ่านการแก้ปัญหาเท่านั้น
นั่นคือการกำหนดฟังก์ชั่นอื่นภายในฟังก์ชั่น
ฟังก์ชั่น f1 () {var n = 999; ฟังก์ชั่น f2 () {แจ้งเตือน (n); // 999}}ในรหัสด้านบนฟังก์ชั่น F2 รวมอยู่ในฟังก์ชั่น F1 และตัวแปรท้องถิ่นทั้งหมดภายใน F1 สามารถมองเห็นได้ที่ F2 แต่วิธีอื่น ๆ ก็เป็นไปไม่ได้ ตัวแปรท้องถิ่นภายใน F2 นั้นมองไม่เห็นที่ F1 นี่คือโครงสร้าง "ขอบเขตโซ่" ที่ไม่ซ้ำกับภาษาจาวาสคริปต์ วัตถุลูกจะมองขึ้นไปตามระดับตามระดับสำหรับตัวแปรวัตถุแม่ทั้งหมด ดังนั้นตัวแปรทั้งหมดของวัตถุหลักจะมองเห็นได้จากวัตถุลูกไม่เช่นนั้นจะไม่เป็นความจริง
เนื่องจาก F2 สามารถอ่านตัวแปรท้องถิ่นใน F1 ได้ตราบใดที่ F2 ใช้เป็นค่าส่งคืนเราไม่สามารถอ่านตัวแปรภายในนอก F1 ได้หรือไม่?
ฟังก์ชั่น f1 () {var n = 999; ฟังก์ชั่น f2 () {แจ้งเตือน (n); } return f2;} var result = f1 (); result (); // 9994.2. จะบันทึกค่าของตัวแปรในหน่วยความจำได้อย่างไร?
ฟังก์ชั่น f1 () {var n = 999; nadd = function () {n+= 1} ฟังก์ชั่น f2 () {การแจ้งเตือน (n); } return f2;} var result = f1 (); result (); // 999nadd (); ผลลัพธ์ (); // 1,000ในรหัสนี้ผลลัพธ์คือฟังก์ชั่นปิด F2 มันทำงานทั้งหมดสองครั้งค่าแรกคือ 999 และค่าที่สองคือ 1,000 นี่พิสูจน์ได้ว่าตัวแปรท้องถิ่นในฟังก์ชั่น F1 ถูกเก็บไว้ในหน่วยความจำและไม่ได้รับการล้างโดยอัตโนมัติหลังจากเรียก F1 โดยอัตโนมัติ
ทำไมสิ่งนี้ถึงเกิดขึ้น? เหตุผลก็คือ F1 เป็นฟังก์ชั่นหลักของ F2 และ F2 ถูกกำหนดให้กับตัวแปรทั่วโลกซึ่งทำให้ F2 อยู่ในหน่วยความจำเสมอและการมีอยู่ของ F2 ขึ้นอยู่กับ F1 ดังนั้น F1 จึงอยู่ในหน่วยความจำเสมอและจะไม่ถูกรีไซเคิลโดยกลไกการรวบรวมขยะหลังจากการโทรเสร็จสิ้น
อีกจุดสำคัญในรหัสนี้คือบรรทัด "nadd = function () {n+= 1}" ถูกใช้ก่อน NADD ดังนั้น NADD จึงเป็นตัวแปรส่วนกลางไม่ใช่ตัวแปรท้องถิ่น ประการที่สองค่าของ NADD เป็นฟังก์ชั่นที่ไม่ระบุชื่อและฟังก์ชั่นนิรนามนี้เองก็เป็นการปิดดังนั้น NADD จึงเทียบเท่ากับ setter ซึ่งสามารถทำงานกับตัวแปรท้องถิ่นภายในฟังก์ชั่นนอกฟังก์ชั่น
5. ปิดและวัตถุนี้
การใช้วัตถุนี้ในการปิดอาจทำให้เกิดปัญหาบางอย่าง เนื่องจากการดำเนินการของฟังก์ชั่นที่ไม่ระบุชื่อเป็นทั่วโลกวัตถุนี้มักจะชี้ไปที่หน้าต่าง รหัสมีดังนี้:
var name = "the window"; var object = {ชื่อ: "my object", getNameFun: function () {return function () {return this.name;};}}; alert (object.getNameFun () {}); // "หน้าต่าง" (ในโหมดที่ไม่ใช่ Strict)บันทึกวัตถุนี้ในขอบเขตภายนอกในตัวแปรที่สามารถเข้าถึงได้โดยการปิดและการปิดสามารถเข้าถึงวัตถุ รหัสมีดังนี้:
var name = "the window"; var object = {ชื่อ: "my object", getNameFun: function () {var that = this; return function () {return that.name;};}}; Alert (Object.getNameFun () {}); // "วัตถุของฉัน"6. การปิดและการรั่วไหลของหน่วยความจำ
โดยเฉพาะอย่างยิ่งหากองค์ประกอบ HTML ถูกเก็บไว้ในขอบเขตของการปิดหมายความว่าองค์ประกอบไม่สามารถทำลายได้ ดังนี้:
ฟังก์ชั่นกำหนดค่า () {var element = document.getElementById ("onelement"); element.onclick = function () {Alert (element.id);}}รหัสด้านบนสร้างการปิดเป็นตัวจัดการเหตุการณ์องค์ประกอบและการปิดนี้จะสร้างการอ้างอิงแบบวงกลม เนื่องจากฟังก์ชั่นที่ไม่ระบุชื่อบันทึกการอ้างอิงไปยังวัตถุที่ใช้งานอยู่ของ AssignHandler () จึงไม่สามารถลดจำนวนการอ้างอิงไปยังองค์ประกอบได้ ตราบใดที่มีฟังก์ชั่นที่ไม่ระบุชื่อจำนวนการอ้างอิงถึงองค์ประกอบอย่างน้อย 1 ดังนั้นหน่วยความจำที่ใช้งานจะไม่ถูกนำกลับมาใช้ใหม่
แก้ไขปัญหาการรีไซเคิลภายในโดยการเขียนรหัสใหม่:
ฟังก์ชั่น asignhandler () {var element = document.getElementById ("บางส่วน"); var id = element.id; element.onclick = function () {Alert (id);} element = null;}ในรหัสข้างต้นการปิดการใช้งานไม่ได้อ้างถึงองค์ประกอบโดยตรงและการอ้างอิงจะยังคงถูกบันทึกไว้ในวัตถุที่ใช้งานที่มีฟังก์ชั่น ดังนั้นจึงจำเป็นต้องตั้งค่าตัวแปรองค์ประกอบเป็นโมฆะเพื่อให้หน่วยความจำที่อยู่อาศัยสามารถรีไซเคิลได้ตามปกติ
7. หมายเหตุเกี่ยวกับการใช้การปิด
1) เนื่องจากการปิดจะทำให้ตัวแปรทั้งหมดในฟังก์ชันถูกเก็บไว้ในหน่วยความจำและการใช้หน่วยความจำมีขนาดใหญ่มากการปิดไม่สามารถถูกทารุณกรรมไม่เช่นนั้นจะทำให้เกิดปัญหาประสิทธิภาพของหน้าเว็บและอาจนำไปสู่การรั่วไหลของหน่วยความจำใน IE วิธีแก้ปัญหาคือการลบตัวแปรท้องถิ่นทั้งหมดที่ไม่ได้ใช้ก่อนออกจากฟังก์ชั่น
2) การปิดจะเปลี่ยนค่าของตัวแปรภายในฟังก์ชั่นหลักนอกฟังก์ชั่นหลัก ดังนั้นหากคุณใช้ฟังก์ชั่นหลักเป็นวัตถุให้ใช้การปิดเป็นวิธีการสาธารณะและใช้ตัวแปรภายในเป็นคุณสมบัติส่วนตัวโปรดระวังอย่าเปลี่ยนค่าของตัวแปรภายในของฟังก์ชันหลักที่จะ
ข้างต้นเป็นคำอธิบายโดยละเอียดเกี่ยวกับการเขียนและฟังก์ชั่นของการปิดใน JavaScript แนะนำให้คุณรู้จักโดยบรรณาธิการ ฉันหวังว่ามันจะเป็นประโยชน์กับคุณ หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับคุณทันเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!