คำนำ: ยังคงเป็นบทความเบื้องต้น มีคุณสมบัติภาษาที่สำคัญหลายประการใน JavaScript - วัตถุการสืบทอดต้นแบบและการปิด ในหมู่พวกเขาการปิดเป็นคุณลักษณะภาษาใหม่สำหรับโปรแกรมเมอร์ที่ใช้ภาษาคงที่แบบดั้งเดิม C/C ++ บทความนี้จะเริ่มต้นด้วยตัวอย่างเพื่อแนะนำคุณสมบัติทางภาษาของการปิด JavaScript และรวมข้อมูลจำเพาะภาษา ECMASCRIPT บางอย่างเพื่อให้ผู้อ่านเข้าใจการปิดอย่างลึกซึ้งยิ่งขึ้น
หมายเหตุ: บทความนี้เป็นบทความเบื้องต้นและวัสดุตัวอย่างถูกรวบรวมบนอินเทอร์เน็ต หากคุณเป็นอาจารย์คุณสามารถนำเสนอข้อเสนอแนะทางเทคนิคและความคิดเห็นในบทความ บทความนี้กล่าวถึง JavaScript และคุณไม่ต้องการเปรียบเทียบภาษา หากคุณรู้สึกไม่สบายใจกับ JavaScript โดยธรรมชาติโปรดใช้ทางอ้อม
การปิดคืออะไร
การปิดคืออะไร? การปิดคือการปิดซึ่งเป็นคุณสมบัติใหม่ที่ภาษาคงที่ไม่มี แต่การปิดไม่ใช่สิ่งที่ซับซ้อนมากจนไม่สามารถเข้าใจได้ ในระยะสั้นการปิดคือ:
การปิดเป็นชุดของตัวแปรท้องถิ่นของฟังก์ชั่น แต่ตัวแปรท้องถิ่นเหล่านี้จะยังคงมีอยู่หลังจากฟังก์ชั่นกลับมา
การปิดเป็น "สแต็ค" ของฟังก์ชั่นและจะไม่ถูกปล่อยออกมาหลังจากฟังก์ชั่นกลับมา นอกจากนี้เรายังสามารถเข้าใจได้ว่าสแต็คฟังก์ชั่นเหล่านี้ไม่ได้จัดสรรบนสแต็ก แต่ได้รับการจัดสรรบนกอง
เมื่อกำหนดฟังก์ชั่นอื่นภายในฟังก์ชั่นการปิดจะถูกสร้างขึ้น
คำจำกัดความที่สองด้านบนเป็นคำอธิบายเพิ่มเติมครั้งแรกซึ่งแยกวัตถุที่ได้รับการรับรองหัวเรื่องของคำจำกัดความแรก - การปิดเป็นชุดของ 'ตัวแปรท้องถิ่น' ของฟังก์ชัน เป็นเพียงว่าตัวแปรท้องถิ่นนี้สามารถเข้าถึงได้หลังจากที่ฟังก์ชั่นส่งคืน (นี่ไม่ใช่คำจำกัดความอย่างเป็นทางการ แต่คำจำกัดความนี้ควรเอื้อต่อความเข้าใจของคุณเกี่ยวกับการปิด)
ในฐานะตัวแปรท้องถิ่นพวกเขาสามารถเข้าถึงได้ด้วยรหัสในฟังก์ชั่นและไม่มีความแตกต่างระหว่างภาษานี้และภาษาคงที่ ความแตกต่างระหว่างการปิดคือตัวแปรท้องถิ่นยังสามารถเข้าถึงได้ด้วยรหัสนอกฟังก์ชั่นหลังจากฟังก์ชั่นถูกเรียกใช้งาน ซึ่งหมายความว่าฟังก์ชั่นจะต้องส่งคืน "การอ้างอิง" ไปยังการปิดหรือกำหนด "การอ้างอิง" นี้ให้กับตัวแปรภายนอกเพื่อให้แน่ใจว่าตัวแปรท้องถิ่นในการปิดสามารถเข้าถึงได้ด้วยรหัสภายนอก แน่นอนเอนทิตีที่มีการอ้างอิงนี้ควรเป็นวัตถุเพราะใน JavaScript ส่วนที่เหลือทั้งหมดยกเว้นประเภทพื้นฐานเป็นวัตถุ น่าเสียดายที่ ECMASCript ไม่ได้ให้สมาชิกและวิธีการที่เกี่ยวข้องในการเข้าถึงตัวแปรท้องถิ่นในการปิด อย่างไรก็ตามใน ECMASCript ฟังก์ชั่นด้านในที่กำหนดไว้ในวัตถุฟังก์ชันเป็นตัวแปรท้องถิ่นที่สามารถเข้าถึงฟังก์ชั่นภายนอกโดยตรง ด้วยกลไกนี้เราสามารถเข้าถึงการปิดด้วยวิธีต่อไปนี้
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่นทักทาย (ชื่อ) {
var text = 'hello' + ชื่อ; // ตัวแปรท้องถิ่น
// ทุกครั้งที่มีการสร้างการปิดและวัตถุฟังก์ชันภายในจะถูกส่งกลับไปยังผู้โทร
return function () {Alert (ข้อความ); -
-
var sayshello = ทักทาย ("ปิด");
sayshello () // เข้าถึงข้อความตัวแปรท้องถิ่นผ่านการปิด
ผลการดำเนินการของรหัสข้างต้นคือ: การปิดสวัสดีเพราะหลังจากฟังก์ชั่นการทักทายนั้นฟังก์ชั่น Sayhello () ยังสามารถเข้าถึงข้อความตัวแปรท้องถิ่นที่กำหนดไว้ภายใน
ตกลงนี่คือผลของการปิดตำนาน การปิดมีสถานการณ์แอปพลิเคชันและโหมดมากมายใน JavaScript เช่น Singleton, Power Constructor และโหมด JavaScript อื่น ๆ ที่แยกออกไม่ได้จากการใช้การปิด
แบบจำลองการปิด Ecmascript
ECMASCRIPT ใช้งานการปิดอย่างไร หากคุณต้องการมีความเข้าใจในเชิงลึกคุณสามารถรับข้อมูลจำเพาะของ ECMASCRIPT สำหรับการวิจัย ฉันจะให้คำอธิบายง่ายๆที่นี่และเนื้อหาก็มาจากอินเทอร์เน็ต
เมื่อฟังก์ชั่นของสคริปต์ eCmascript ทำงานแต่ละการเชื่อมโยงฟังก์ชั่นมีสถานการณ์บริบทการดำเนินการ (บริบทการดำเนินการ) ซึ่งมีสามส่วน
คำศัพท์
ตัวแปร
การผูกมัดนี้
จุดที่สามของการผูกมัดนี้ไม่มีส่วนเกี่ยวข้องกับการปิดและไม่ได้กล่าวถึงในบทความนี้ ตัวระบุตัวแปรที่ใช้ในสภาพแวดล้อมทางไวยากรณ์สำหรับการแยกวิเคราะห์กระบวนการดำเนินการฟังก์ชั่น เราสามารถนึกถึงสภาพแวดล้อมทางไวยากรณ์เป็นวัตถุที่มีสององค์ประกอบที่สำคัญบันทึกสภาพแวดล้อม (enviroment recode) และการอ้างอิงภายนอก (ตัวชี้) บันทึกสภาพแวดล้อมมีตัวแปรท้องถิ่นและตัวแปรพารามิเตอร์ที่ประกาศภายในฟังก์ชันและจุดอ้างอิงภายนอกไปยังสถานการณ์การดำเนินการตามบริบทของวัตถุฟังก์ชันภายนอก ค่าอ้างอิงนี้เป็นโมฆะในสถานการณ์บริบททั่วโลก โครงสร้างข้อมูลดังกล่าวเป็นรายการที่เชื่อมโยงทางเดียวแต่ละรายการอ้างอิงชี้ไปยังสถานการณ์บริบทภายนอก
ตัวอย่างเช่นรูปแบบการปิดในตัวอย่างของเราด้านบนควรเป็นเช่นนี้ ฟังก์ชั่น Sayhello อยู่ในระดับต่ำสุดระดับบนคือการทักทายฟังก์ชั่นและระดับนอกสุดคือฉากระดับโลก ดังที่แสดงในรูปด้านล่าง: ดังนั้นเมื่อเรียกว่า sayhello sayshello จะพบค่าของข้อความตัวแปรท้องถิ่นผ่านฉากบริบทดังนั้นสภาพแวดล้อมตัวแปร "สวัสดีปิด" (ตัวแปร jariableEnvironment) และสภาพแวดล้อมไวยากรณ์นั้นเหมือนกัน สำหรับความแตกต่างเฉพาะโปรดดูเอกสารข้อกำหนด ECMASCRIPT
คอลัมน์ตัวอย่างของการปิด
ในบทความก่อนหน้านี้ฉันเข้าใจอย่างถ่องแท้ว่าการปิด JavaScript คืออะไรและการปิดใช้งานใน JavaScript ด้านล่างเราจะช่วยให้คุณเข้าใจการปิดอย่างลึกซึ้งยิ่งขึ้นโดยกำหนดเป้าหมายตัวอย่าง มี 5 ตัวอย่างด้านล่างและตัวอย่างมาจากการปิด JavaScript สำหรับ Dummies (Mirror) ตัวอย่างที่ 1: ตัวแปรท้องถิ่นในการปิดเป็นการอ้างอิงมากกว่าสำเนา
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่นบอกว่า 667 () {
// ตัวแปรท้องถิ่นที่จบลงด้วยการปิด
var num = 666;
var saysalert = function () {alert (num); -
num ++;
กลับมาพูดคุย;
-
var saysalert = say667 ();
Sayalert ()
ดังนั้นผลการดำเนินการควรปรากฏขึ้น 667 แทน 666
ตัวอย่างที่ 2: ฟังก์ชั่นหลายฟังก์ชั่นเชื่อมโยงการปิดเดียวกันเนื่องจากถูกกำหนดไว้ในฟังก์ชั่นเดียวกัน
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น setupSomeGlobals () {
// ตัวแปรท้องถิ่นที่จบลงด้วยการปิด
var num = 666;
// จัดเก็บการอ้างอิงถึงฟังก์ชั่นเป็นตัวแปรทั่วโลก
galertNumber = function () {Alert (num); -
gincreasenumber = function () {num ++; -
gsetNumber = function (x) {num = x; -
-
SetupSomeGlobals (); // กำหนดค่าให้กับสามตัวแปรทั่วโลก
Galertnumber (); // 666
gincreasenumber ();
Galertnumber (); // 667
gsetNumber (12); //
galertnumber (); // 12
ตัวอย่างที่ 3: เมื่อกำหนดฟังก์ชั่นในลูปฟังก์ชั่นเหล่านี้จะเชื่อมต่อการปิดเดียวกัน
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น buildlist (รายการ) {
var result = [];
สำหรับ (var i = 0; i <list.length; i ++) {
var item = 'item' + list [i];
result.push (function () {alert (item + '' + list [i])});
-
ผลการกลับมา;
-
ฟังก์ชัน testList () {
var fnlist = buildList ([1,2,3]);
// การใช้ J เพียงเพื่อช่วยป้องกันความสับสน - สามารถใช้ฉันได้
สำหรับ (var j = 0; j <fnlist.length; j ++) {
fnlist [j] ();
-
-
ผลการดำเนินการของ TestList คือหน้าต่างที่ไม่ได้กำหนดรายการ 3 จะปรากฏขึ้นสามครั้งเนื่องจากฟังก์ชั่นทั้งสามนี้ผูกมัดการปิดเดียวกันและค่าของรายการเป็นผลลัพธ์ที่คำนวณได้ล่าสุด แต่เมื่อฉันกระโดดออกจากลูปค่า I คือ 4 ดังนั้นผลลัพธ์ของรายการ [4] จะไม่ถูกกำหนด
ตัวอย่างที่ 4: ตัวแปรท้องถิ่นทั้งหมดของฟังก์ชั่นภายนอกอยู่ในการปิดแม้ว่าตัวแปรนี้จะถูกประกาศหลังจากนิยามฟังก์ชั่นภายใน
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น saysalice () {
var saysalert = function () {Alert (Alice); -
// ตัวแปรท้องถิ่นที่จบลงด้วยการปิด
var Alice = 'Hello Alice';
กลับมาพูดคุย;
-
var helloalice = sayalice ();
Helloalice ();
ผลการดำเนินการเป็นหน้าต่างที่มีป๊อปอัพ "Hello Alice" แม้ว่าตัวแปรท้องถิ่นจะประกาศหลังจากฟังก์ชั่น saydalert ตัวแปรท้องถิ่นยังสามารถเข้าถึงได้
ตัวอย่างที่ 5: สร้างการปิดใหม่ทุกครั้งที่เรียกว่าฟังก์ชั่น
การคัดลอกรหัสมีดังนี้:
ฟังก์ชั่น newclosure (somenum, someref) {
// ตัวแปรท้องถิ่นที่จบลงด้วยการปิด
var num = somenum;
var anarray = [1,2,3];
var ref = someref;
ฟังก์ชั่น return (x) {
num += x;
anarray.push (num);
การแจ้งเตือน ('num:' + num +
'/nanarray' + anarray.toString () +
'/nref.somevar' + ref.somevar);
-
-
ปิด 1 = newClosure (40, {somevar: 'ปิด 1'});
ปิด 2 = newClosure (1,000, {somevar: 'ปิด 2'});
ปิด 1 (5); // num: 45 anarray [1,2,3,45] ref: 'somevar ปิด 1'
ปิด 2 (-10); // num: 990 anarray [1,2,3,990] ref: 'somevar ปิด 2'
การประยุกต์ใช้การปิด
ซิงเกิลตันชิ้นเดียว:
การคัดลอกรหัสมีดังนี้:
var singleton = function () {
var privatevariable;
ฟังก์ชั่น PrivateFunction (x) {
... PrivateVariable ...
-
กลับ {
FirstMethod: ฟังก์ชั่น (a, b) {
... PrivateVariable ...
-
SecondMethod: function (c) {
... PrivateFunction () ...
-
-
-
ชิ้นเดียวนี้ประสบความสำเร็จผ่านการปิด การห่อหุ้มของสมาชิกเอกชนและวิธีการเสร็จสิ้นผ่านการปิด ฟังก์ชั่นหลักที่ไม่ระบุชื่อส่งคืนวัตถุ วัตถุมีสองวิธีวิธีการที่ 1 สามารถใช้ตัวแปรส่วนตัวและวิธีการที่ 2 สามารถเข้าถึงฟังก์ชั่นส่วนตัวภายใน สิ่งที่ควรทราบคือ '()' ซึ่งฟังก์ชั่นหลักที่ไม่ระบุชื่อสิ้นสุดลง หากไม่มีสิ่งนี้ '()' ชิ้นเดียวจะไม่สามารถผลิตได้ เนื่องจากฟังก์ชั่นที่ไม่ระบุชื่อสามารถส่งคืนวัตถุที่ไม่ซ้ำกันเท่านั้นและไม่สามารถเรียกได้ที่อื่น นี่คือวิธีการใช้การปิดเพื่อสร้างชิ้นส่วนเดียว