หนึ่งในคุณสมบัติที่สำคัญที่สุดใน JavaScript คือการใช้การปิด เนื่องจากการใช้งานปิดขอบเขตปัจจุบันสามารถเข้าถึงขอบเขตภายนอกได้เสมอ เนื่องจาก JavaScript ไม่มีขอบเขตระดับบล็อกและขอบเขตฟังก์ชันเท่านั้นการใช้การปิดจึงเกี่ยวข้องกับฟังก์ชั่นอย่างใกล้ชิด
จำลองตัวแปรส่วนตัว
การคัดลอกรหัสมีดังนี้:
ตัวนับฟังก์ชัน (เริ่มต้น) {
count var = start;
กลับ {
เพิ่มขึ้น: function () {
นับ ++;
-
รับ: function () {
นับคืน;
-
-
-
var foo = counter (4);
foo.increment ();
foo.get (); // 5
ที่นี่เคาน์เตอร์ส่งคืนการปิดสองครั้ง: ฟังก์ชั่นเพิ่มขึ้นและรับ ฟังก์ชั่นทั้งสองนี้รักษาการเข้าถึงขอบเขตตัวนับดังนั้นพวกเขาจึงสามารถเข้าถึงจำนวนตัวแปรที่กำหนดไว้ในขอบเขตการนับ
กลไกการทำงานของตัวแปรส่วนตัว
เนื่องจาก JavaScript ไม่สามารถกำหนดค่าและการอ้างอิงไปยังขอบเขตในตัวอย่างข้างต้นจึงไม่มีวิธีที่จะเข้าถึงจำนวนตัวแปรส่วนตัวภายในโดยตรงจากภายนอก วิธีเดียวคือการเข้าถึงโดยการกำหนดปิด
การคัดลอกรหัสมีดังนี้:
var foo = ตัวนับใหม่ (4);
foo.hack = function () {
นับ = 1337;
-
รหัสข้างต้นไม่เปลี่ยนค่าของตัวแปรนับภายในขอบเขตตัวนับเนื่องจากการแฮ็กไม่ได้กำหนดไว้ในตัวนับ รหัสข้างต้นจะสร้างหรือเขียนทับจำนวนตัวแปรส่วนกลางเท่านั้น
ปิดในวง
หนึ่งในข้อผิดพลาดที่ง่ายที่สุดคือการใช้การปิดภายในวง
การคัดลอกรหัสมีดังนี้:
สำหรับ (var i = 0; i <10; i ++) {
settimeout (function () {
console.log (i);
}, 1,000);
-
รหัสข้างต้นจะไม่ส่งออก 0 ถึง 9 แต่จะส่งออก 10 ครั้งอย่างต่อเนื่อง
การไม่เปิดเผยตัวตนข้างต้นจะอ้างอิงถึงตัวแปร i เมื่อฟังก์ชั่น console.log ถูกเรียกให้เริ่มส่งออกนี่คือลูปที่สิ้นสุดลงและตัวแปรที่ฉัน 10 อยู่แล้ว
เพื่อหลีกเลี่ยงข้อผิดพลาดข้างต้นเราจำเป็นต้องสร้างสำเนาของตัวแปรที่ฉันให้ค่าในแต่ละครั้งที่เราวนซ้ำ
หลีกเลี่ยงข้อผิดพลาดใบเสนอราคา
ในการคัดลอกค่าของตัวแปรในลูปวิธีที่ดีที่สุดคือการเพิ่มฟังก์ชั่นที่ไม่ระบุชื่อให้กับเลเยอร์ด้านนอกและดำเนินการทันที
การคัดลอกรหัสมีดังนี้:
สำหรับ (var i = 0; i <10; i ++) {
(ฟังก์ชั่น (e) {
settimeout (function () {
console.log (e);
}, 1,000);
})(ฉัน);
-
ฟังก์ชั่นที่ไม่ระบุชื่อภายนอกนี้ใช้ตัวแปรลูป I เป็นพารามิเตอร์แรกและคัดลอกค่าไปยังพารามิเตอร์ของตัวเอง
ฟังก์ชั่นที่ไม่ระบุชื่อภายนอกผ่านพารามิเตอร์ e ไปยัง settimeout ดังนั้น settimeout จึงมีการอ้างอิงถึงพารามิเตอร์ e ยิ่งไปกว่านั้นค่าของพารามิเตอร์นี้จะไม่เปลี่ยนแปลงเนื่องจากการเปลี่ยนแปลงลูปภายนอก
มีอีกวิธีหนึ่งในการบรรลุเอฟเฟกต์เดียวกันซึ่งก็คือการส่งคืนฟังก์ชั่นที่ไม่ระบุชื่อในฟังก์ชั่นที่ไม่ระบุชื่อใน Settimeout:
การคัดลอกรหัสมีดังนี้:
สำหรับ (var i = 0; i <10; i ++) {
Settimeout ((ฟังก์ชั่น (e) {
return function () {
console.log (e);
-
}) (i), 1000)
-
นอกจากนี้ยังสามารถทำได้ด้วยวิธีการผูก
การคัดลอกรหัสมีดังนี้:
สำหรับ (var i = 0; i <10; i ++) {
settimeout (console.log.bind (คอนโซล, i), 1,000);
-
ในตอนท้ายของบทความมาสรุปกันเถอะ:
(1) การปิดเป็นหลักการออกแบบ มันทำให้การโทรของผู้ใช้ง่ายขึ้นโดยการวิเคราะห์บริบททำให้ผู้ใช้สามารถบรรลุวัตถุประสงค์ของเขาโดยไม่ทราบ
(2) บทความออนไลน์หลักเกี่ยวกับการวิเคราะห์การปิดนั้นตรงกันข้ามกับหลักการปิด หากคุณต้องการทราบรายละเอียดของการปิดที่จะใช้งานได้ดีการปิดนี้เป็นความล้มเหลวในการออกแบบ
(3) พยายามเรียนรู้ให้น้อยที่สุด