เมื่อเร็ว ๆ นี้ฉันกำลังอ่าน "JavaScript Advanced Programming 3" และรู้สึกว่าฉันควรเขียนบล็อกบางอย่างเพื่อบันทึกความรู้บางอย่างที่ฉันเรียนรู้มิฉะนั้นฉันจะลืมมัน สิ่งที่ฉันต้องการสรุปในวันนี้คือสภาพแวดล้อมและขอบเขตการดำเนินการของ JS
ก่อนอื่นมาพูดคุยเกี่ยวกับสภาพแวดล้อมการดำเนินการ
1. สภาพแวดล้อมการดำเนินการ
แนวคิดในหนังสือสภาพแวดล้อมการดำเนินการกำหนดข้อมูลอื่น ๆ ที่ตัวแปรหรือฟังก์ชั่นมีการเข้าถึงและกำหนดพฤติกรรมที่เกี่ยวข้อง แต่ละสภาพแวดล้อมการดำเนินการมีวัตถุตัวแปรที่เกี่ยวข้อง ตัวแปรและฟังก์ชั่นทั้งหมดที่กำหนดไว้ในสภาพแวดล้อมจะถูกเก็บไว้ในวัตถุนี้ แม้ว่าเราจะไม่สามารถเข้าถึงวัตถุนี้ได้เมื่อเขียนโค้ด แต่ตัวแยกวิเคราะห์จะใช้มันในพื้นหลังเมื่อประมวลผลข้อมูล
สภาพแวดล้อมการดำเนินการเป็นแนวคิดซึ่งเป็นกลไกที่กำหนดว่าตัวแปรหรือฟังก์ชั่นได้รับอนุญาตให้เข้าถึงข้อมูลอื่น ๆ
ใน JavaScript รหัส JavaScript ที่ใช้งานได้แบ่งออกเป็นสามประเภท:
1. รหัสส่วนกลางนั่นคือรหัสส่วนกลางที่ไม่ได้อยู่ในฟังก์ชันใด ๆ เช่นไฟล์ JS, รหัส JS ที่ฝังอยู่ในหน้า HTML ฯลฯ
2. รหัสประเมินนั่นคือรหัส JS ที่ดำเนินการแบบไดนามิกโดยใช้ฟังก์ชัน eval ()
3. รหัสฟังก์ชั่นนั่นคือรหัสฟังก์ชัน Body JS ในฟังก์ชั่นที่ผู้ใช้กำหนด
ข้ามรหัสการประเมินและพูดคุยเกี่ยวกับสภาพแวดล้อมการดำเนินการทั่วโลกและสภาพแวดล้อมการดำเนินการฟังก์ชั่น
1. สภาพแวดล้อมระดับโลก:
สภาพแวดล้อมทั่วโลกเป็นสภาพแวดล้อมการดำเนินการต่อพ่วงมากที่สุด สภาพแวดล้อมการดำเนินการทั่วโลกถือเป็นวัตถุหน้าต่าง ดังนั้นตัวแปรและฟังก์ชั่นทั่วโลกทั้งหมดจึงถูกสร้างขึ้นเป็นคุณสมบัติและวิธีการของวัตถุหน้าต่าง เมื่อรหัสถูกโหลดลงในเบราว์เซอร์สภาพแวดล้อมการดำเนินการทั่วโลกจะถูกสร้างขึ้น (สภาพแวดล้อมการดำเนินการทั่วโลกจะถูกทำลายเฉพาะเมื่อเราปิดหน้าเว็บหรือเบราว์เซอร์) ตัวอย่างเช่นในหน้าหนึ่งให้สร้างสภาพแวดล้อมการดำเนินการทั่วโลกเมื่อโหลดรหัส JS เป็นครั้งแรก
นี่คือเหตุผลที่การปิดมีข้อเสียของการรั่วไหลของหน่วยความจำ เนื่องจากฟังก์ชั่นภายนอกในการปิดถือเป็นสภาพแวดล้อมระดับโลก ดังนั้นมันจะไม่ถูกทำลายและจะถูกเก็บไว้ในความทรงจำ
2. สภาพแวดล้อมการดำเนินการฟังก์ชั่น
แต่ละฟังก์ชั่นมีสภาพแวดล้อมการดำเนินการของตัวเอง เมื่อการดำเนินการเข้าสู่ฟังก์ชั่นสภาพแวดล้อมการดำเนินการของฟังก์ชั่นจะถูกผลักไปที่ด้านบนของสภาพแวดล้อมการดำเนินการสแต็กและรับสิทธิ์ในการดำเนินการ เมื่อฟังก์ชั่นนี้ถูกดำเนินการสภาพแวดล้อมการดำเนินการจะถูกลบออกจากด้านบนของสแต็กและสิทธิการดำเนินการจะถูกส่งกลับไปยังสภาพแวดล้อมการดำเนินการก่อนหน้านี้ นี่คือโฟลว์การดำเนินการในโปรแกรม ECMASCRIPT
นอกจากนี้ยังสามารถตีความได้ด้วยวิธีนี้: เมื่อเรียกใช้ฟังก์ชัน JavaScript ฟังก์ชั่นจะเข้าสู่สภาพแวดล้อมการดำเนินการที่สอดคล้องกับฟังก์ชั่น หากมีการเรียกฟังก์ชั่นอื่นสภาพแวดล้อมการดำเนินการใหม่จะถูกสร้างขึ้นและกระบวนการดำเนินการอยู่ในสภาพแวดล้อมนั้นในระหว่างการเรียกใช้ฟังก์ชัน เมื่อฟังก์ชั่นที่เรียกว่าส่งคืนกระบวนการดำเนินการจะกลับสู่สภาพแวดล้อมการดำเนินการดั้งเดิม ดังนั้นการเรียกใช้รหัส JavaScript จะสร้างสแต็กสภาพแวดล้อมการดำเนินการ
เมื่อมีการเรียกฟังก์ชั่นสภาพแวดล้อมท้องถิ่นของฟังก์ชั่นจะถูกสร้างขึ้น (หลังจากรหัสในฟังก์ชันถูกดำเนินการสภาพแวดล้อมจะถูกทำลายและตัวแปรและคำจำกัดความของฟังก์ชั่นทั้งหมดที่เก็บไว้ในนั้นก็ถูกทำลายด้วย)
ระยะเวลาการกำหนด 2-1
เมื่อมีการกำหนดฟังก์ชั่นแอตทริบิวต์ [[ขอบเขต]] จะถูกสร้างขึ้น วัตถุนี้สอดคล้องกับรายการของวัตถุ วัตถุในรายการสามารถเข้าถึงได้ภายในโดย JavaScript เท่านั้นและไม่สามารถเข้าถึงได้ผ่านทางไวยากรณ์
(ขอบเขตหมายถึงขอบเขต)
เรากำหนดฟังก์ชั่นทั่วโลก A แล้วฟังก์ชั่น A สร้างแอตทริบิวต์ [[ขอบเขต]] ของ A ในเวลานี้ [[ขอบเขต]] มีเฉพาะวัตถุระดับโลก [วัตถุทั่วโลก]
หากเรากำหนดฟังก์ชัน B ภายใน A ฟังก์ชั่น B จะสร้างแอตทริบิวต์ [[ขอบเขต]] แอตทริบิวต์ [[ขอบเขต]] ของ B มีวัตถุสองวัตถุหนึ่งชิ้นคือวัตถุการเปิดใช้งานวัตถุที่ใช้งานของ Object A ที่ใช้งานอยู่และอีกวัตถุหนึ่งคือวัตถุทั่วโลก วัตถุที่ใช้งานอยู่ของ A อยู่ด้านหน้าและวัตถุระดับโลกอยู่ด้านหลัง
กล่าวโดยย่อลำดับของรายการวัตถุในคุณสมบัติ [ขอบเขต] ของฟังก์ชั่นคือวัตถุวัตถุเปิดใช้งานของเลเยอร์ก่อนหน้าของฟังก์ชันจากนั้นชั้นบนสุดไปจนถึงวัตถุระดับโลกด้านนอกสุด
นี่คือรหัสตัวอย่าง: A มีเพียงขอบเขตเดียว B มีสองขอบเขต
// ฟังก์ชั่นฟังก์ชั่นภายนอก a () {var somevar; // ฟังก์ชั่นฟังก์ชันภายใน b () {var somevar; -2-2 ระยะเวลาดำเนินการ
เมื่อมีการดำเนินการฟังก์ชั่นจะเข้าสู่สภาพแวดล้อมการดำเนินการของฟังก์ชัน ก่อนอื่นมันจะสร้างวัตถุที่ใช้งานของตัวเอง [วัตถุการเปิดใช้งาน] (วัตถุนี้มีคำจำกัดความของสิ่งนี้อาร์กิวเมนต์ตัวแปรท้องถิ่น (รวมถึงพารามิเตอร์ที่มีชื่อ) และโซ่ขอบเขตของวัตถุตัวแปรจากนั้นคัดลอกขอบเขตของสภาพแวดล้อมการดำเนินการ [[ขอบเขตห่วงโซ่]] และวัตถุที่ได้รับอนุญาตให้เข้าถึงสภาพแวดล้อมการดำเนินการ
// ขั้นตอนแรกคือการสร้างสภาพแวดล้อมการดำเนินการทั่วโลก บริบทการดำเนินการทั่วโลกและวัตถุกิจกรรมทั่วโลก // กำหนด global [[ขอบเขต]] ซึ่งมีเฉพาะวัตถุหน้าต่าง // สแกนตัวแปรคำจำกัดความทั่วโลกและวัตถุฟังก์ชัน: สี【 undefined 】, changecolor 【 fd สร้าง changecolor [[ขอบเขต]] ซึ่งมีวัตถุกิจกรรมทั่วโลกเท่านั้น // โปรแกรมได้รับการกำหนดเพื่อให้สามารถดำเนินการ changecolor () ได้ทุกที่ในสภาพแวดล้อมการดำเนินการนี้ สีได้รับการกำหนด แต่ค่าของมันไม่ได้กำหนด // ขั้นตอนที่สองคือการกำหนดสี "สีน้ำเงิน" var color = "blue"; // มันไม่จำเป็นต้องได้รับการกำหนดมันหมายถึงฟังก์ชั่นของตัวเอง changecolor () {// ขั้นตอนที่สี่เข้าสู่สภาพแวดล้อมการดำเนินการ สีอื่น【 undefined 】และ swapcolors 【 fd สร้าง swapcolors [[ขอบเขต]] และเพิ่มวัตถุที่ใช้งานอยู่และวัตถุที่ใช้งานอยู่ทั่วโลก】ลงในวัตถุที่ใช้งานอยู่และเพิ่มอาร์กิวเมนต์และ // วัตถุที่ใช้งานอยู่ สีอื่นได้รับการกำหนด แต่ค่าของมันไม่ได้กำหนด // การกำหนดสีอื่น ๆ ที่ห้า "สีแดง" var otherColor = "สีแดง"; // มันไม่จำเป็นต้องได้รับมอบหมายมันหมายถึงฟังก์ชั่นของตัวเอง swapcolors () {// ขั้นตอนที่ 7 ป้อนสภาพแวดล้อมการดำเนินการของ swapcolors และสร้างวัตถุที่ใช้งานอยู่ // คัดลอก swapcolors '[[ขอบเขต]] เพื่อขอบเขตโซ่ // สแกนเพื่อกำหนดตัวแปร ค่าการกำหนดค่า tempColor ของสีอื่นสีอื่นและสีจะพบได้ตามห่วงโซ่ขอบเขตและดำเนินการต่อเพื่อดำเนินการ var tempColor = สีอื่น; สีอื่น = สี; สี = tempColor; } // ขั้นตอนที่ 6: ดำเนินการ swapcolors และป้อนสภาพแวดล้อมการดำเนินการ swapcolors ();} // ขั้นตอนที่ 3: ดำเนินการ changecolor และป้อนสภาพแวดล้อมการดำเนินการ changecolor ();2-3 ตัวระบุการเข้าถึง:
เมื่อพบตัวระบุในระหว่างการดำเนินการของรหัส JS มันจะค้นหาในขอบเขตห่วงโซ่ของบริบทการดำเนินการ (บริบทการดำเนินการ) ตามชื่อของตัวระบุ เริ่มต้นจากวัตถุแรกของห่วงโซ่ขอบเขต (วัตถุการเปิดใช้งานของฟังก์ชัน) หากไม่พบให้ค้นหาวัตถุถัดไปในโซ่ขอบเขตและทำซ้ำจนกว่าจะพบคำจำกัดความตัวระบุ หากไม่พบวัตถุสุดท้ายในขอบเขตหลังจากค้นหาการค้นหานั่นคือวัตถุส่วนกลาง (วัตถุทั่วโลก) ข้อผิดพลาดจะถูกโยนออก
2. ขอบเขต/ขอบเขตโซ่ (ขอบเขต/ขอบเขตโซ่)
เมื่อรหัสถูกดำเนินการในสภาพแวดล้อมจะมีการสร้างห่วงโซ่ขอบเขต จุดประสงค์ของห่วงโซ่ขอบเขตคือเพื่อให้แน่ใจว่าการเข้าถึงตัวแปรและฟังก์ชั่นทั้งหมดเป็นระเบียบที่เป็นระเบียบที่ได้รับอนุญาตให้เข้าถึงสภาพแวดล้อมการดำเนินการ ห่วงโซ่ขอบเขตทั้งหมดเป็นรายการที่เชื่อมโยงที่สร้างขึ้นโดยวัตถุตัวแปรที่ตำแหน่งการดำเนินการที่แตกต่างกันตามกฎ ส่วนหน้าของห่วงโซ่ขอบเขตมักจะเป็นวัตถุตัวแปรในสภาพแวดล้อมที่รหัสกำลังดำเนินการอยู่ในปัจจุบันอยู่
หากสภาพแวดล้อมนี้เป็นฟังก์ชันวัตถุการเปิดใช้งานจะใช้เป็นวัตถุตัวแปร วัตถุที่ใช้งานมีเพียงตัวแปรเดียวที่จุดเริ่มต้นซึ่งเป็นวัตถุอาร์กิวเมนต์ภายในฟังก์ชัน วัตถุตัวแปรถัดไปในห่วงโซ่ขอบเขตมาจากสภาพแวดล้อมการรวมของฟังก์ชั่นและวัตถุตัวแปรถัดไปมาจากสภาพแวดล้อมการรวมครั้งต่อไป ด้วยวิธีนี้มันยังคงดำเนินต่อไปยังสภาพแวดล้อมการดำเนินการทั่วโลกและวัตถุตัวแปรของสภาพแวดล้อมการดำเนินการทั่วโลกเป็นวัตถุสุดท้ายในห่วงโซ่ขอบเขตเสมอ
ดังแสดงในรูป:
ตัวอย่างในหนังสือ:
var color = "Blue"; ฟังก์ชั่น changecolor () {var otherColor = "สีแดง"; ฟังก์ชั่น swapColors () {var tempColor = อื่นสี; สีอื่น = สี; สี = tempColor; // สิ่งที่ต้องทำ} swapColors ();} changecolor (); // tempcolor และ anocolor ไม่สามารถเข้าถึงได้ที่นี่; แต่สามารถเข้าถึงสีได้การแจ้งเตือน ("สีคือตอนนี้"+สี);ผ่านการวิเคราะห์ข้างต้นเราสามารถรู้ได้ว่าสภาพแวดล้อมภายในสามารถเข้าถึงสภาพแวดล้อมภายนอกทั้งหมดผ่านห่วงโซ่ขอบเขต แต่สภาพแวดล้อมภายนอกไม่สามารถเข้าถึงตัวแปรและฟังก์ชั่นใด ๆ ในสภาพแวดล้อมภายใน
สภาพแวดล้อมเหล่านี้เป็นเส้นตรงและเป็นระเบียบ แต่ละสภาพแวดล้อมสามารถค้นหาขอบเขตขอบเขตขึ้นไปยังตัวแปรสอบถามและชื่อฟังก์ชั่น อย่างไรก็ตามสภาพแวดล้อมใด ๆ ไม่สามารถเข้าสู่สภาพแวดล้อมการดำเนินการอื่นได้โดยการค้นหาขอบเขตของห่วงโซ่ลดลง
สำหรับฟังก์ชั่น swapcolor () ในตัวอย่างข้างต้นโซ่ขอบเขตของมันรวมถึง: วัตถุตัวแปร swapcolor () วัตถุตัวแปร changecolor () และวัตถุทั่วโลก สภาพแวดล้อมท้องถิ่นของ SwapColor () เริ่มค้นหาตัวแปรและชื่อฟังก์ชันในวัตถุตัวแปรของตัวเอง หากไม่สามารถพบได้ให้ค้นหาห่วงโซ่ขอบเขตการเปลี่ยนแปลงขึ้นไป - - - - และอื่น ๆ อย่างไรก็ตามฟังก์ชั่น changecolor () ไม่สามารถเข้าถึงตัวแปรใน swapcolor
วิวรณ์: พยายามใช้ตัวแปรท้องถิ่นเพื่อลดเวลาในการค้นหา
1. ไม่มีขอบเขตระดับบล็อก
ซึ่งแตกต่างจาก C, C ++ และ Java, JavaScript ไม่มีขอบเขตระดับบล็อก ดูรหัสต่อไปนี้:
ถ้า (จริง) {var myvar = "จางซาน"; } Alert (MyVar); // Zhang Sanหากมีขอบเขตระดับบล็อก MyVar ไม่สามารถเข้าถึงได้จากภายนอก ดูสิ่งต่อไปนี้
สำหรับ (var i = 0; i <10; i ++) {console.log (i)} การแจ้งเตือน (i); // 10สำหรับภาษาที่มีขอบเขตระดับบล็อกเช่นรหัส Java หรือ C# ฉันเป็นตัวแปรที่เริ่มต้นและไม่สามารถเข้าถึงได้ภายนอก เนื่องจากฉันมีอยู่ในน้ำหนักลูปเท่านั้นหลังจากเรียกใช้สำหรับลูปตัวแปรทั้งหมดใน For จะถูกทำลาย นี่ไม่ใช่กรณีใน JavaScript การประกาศตัวแปรใน FOR จะถูกเพิ่มเข้าไปในสภาพแวดล้อมการดำเนินการปัจจุบัน (นี่คือสภาพแวดล้อมการดำเนินการทั่วโลก) ดังนั้นหลังจากที่ลูปเสร็จสมบูรณ์ตัวแปรที่ฉันยังคงมีอยู่ในสภาพแวดล้อมการดำเนินการนอกลูป ดังนั้น 10 จะเป็นเอาต์พุต
2. ประกาศตัวแปร
เมื่อมีการประกาศตัวแปรโดยใช้ VAR ตัวแปรนี้จะถูกเพิ่มเข้ากับสภาพแวดล้อมที่ใกล้ที่สุดโดยอัตโนมัติ สำหรับด้านในของฟังก์ชั่นสภาพแวดล้อมที่ใกล้เคียงที่สุดคือตัวแปรท้องถิ่นของฟังก์ชั่น หากตัวแปรไม่ได้เริ่มต้นตัวแปรจะถูกเพิ่มลงในฟังก์ชั่นทั่วโลกโดยอัตโนมัติ
รหัสมีดังนี้:
var name = "Xiao Ming"; ฟังก์ชั่น getName () {แจ้งเตือน (ชื่อ); // 'undefined' name = 'Xiao Huang'; การแจ้งเตือน (ชื่อ); // Xiao Huang} getName ()ทำไมชื่อแรกถึงไม่ได้กำหนด? นี่เป็นเพราะตัวแยกวิเคราะห์ JavaScript เข้าสู่สภาพแวดล้อมการทำงานของฟังก์ชั่นและสแกน VAR และฟังก์ชั่นก่อน
มันเทียบเท่ากับการส่งเสริม var หรือฟังก์ชั่น [การประกาศฟังก์ชั่น] การประกาศไปยังด้านบนของสภาพแวดล้อมการดำเนินการ
กล่าวอีกนัยหนึ่งเมื่อป้อนฟังก์ชั่น getName ของเรากลไกการค้นหาตัวระบุพบ var และชื่อเป็นชื่อตัวแปรท้องถิ่นไม่ใช่ชื่อส่วนกลางเนื่องจากชื่อในฟังก์ชั่นได้รับการเลื่อนตำแหน่งไปด้านบน
รหัสข้างต้นจะแยกวิเคราะห์ดังนี้:
var name = "Xiao Ming"; ฟังก์ชั่น getName () {ชื่อ var; การแจ้งเตือน (ชื่อ); // 'undefined' name = 'Xiao Huang'; การแจ้งเตือน (ชื่อ); // Xiao Huang} getName ()ขยายขอบเขตห่วงโซ่:
แม้ว่าจะมีสภาพแวดล้อมการดำเนินการเพียงสองประเภทเท่านั้น - ขอบเขตทั่วโลกและขอบเขตการทำงาน แต่ห่วงโซ่ขอบเขตยังสามารถขยายได้ในบางวิธี เนื่องจากคำสั่งบางอย่างสามารถเพิ่มวัตถุตัวแปรชั่วคราวที่ด้านบนของห่วงโซ่ขอบเขต
มีสองสถานการณ์ที่เกิดขึ้น:
1. บล็อกจับของคำสั่งลองจับ;
2. พร้อมคำสั่ง;
ข้างต้นเป็นเรื่องเกี่ยวกับบทความนี้ ฉันหวังว่ามันจะเป็นประโยชน์สำหรับทุกคนในการเรียนรู้และเข้าใจสภาพแวดล้อมการดำเนินการและขอบเขตการดำเนินการของ JavaScript