ขอบเขตที่เรียกว่าสามารถเข้าใจได้ง่ายว่าเป็นขอบเขต (พื้นที่) ที่สามารถอ่านและเขียนได้ นักเรียนบางคนที่มีประสบการณ์ใน JS อาจพูดว่า: "JS ไม่มีขอบเขตระดับบล็อก" นอกเหนือจากขอบเขตทั่วโลกแล้วฟังก์ชั่นเท่านั้นสามารถสร้างขอบเขตได้ ข้อดีอย่างหนึ่งของขอบเขตคือมันสามารถแยกตัวแปรได้
เราใช้ตัวอย่างบางส่วนเพื่อช่วยให้เราเข้าใจขอบเขตใน JS
การแจ้งเตือน (a); var a = 1;
หากนักเรียนที่ไม่รู้จักขอบเขตทั้งหมดอาจบอกว่าการแจ้งเตือนคือ 1 หรือรายงานข้อผิดพลาด แต่จริง ๆ แล้วมันไม่ได้กำหนด;
ก่อนที่จะพูดถึงสิ่งนี้ก่อนที่จะพูดคุยเกี่ยวกับการเตรียมการบางอย่างก่อนที่ JS จะแยกวิเคราะห์รหัสทีละบรรทัด
ก่อนที่จะอ่านรหัสทีละบรรทัด JS จะทำงาน "pre-parsement" บางอย่างและจะพบ "สิ่งเล็ก ๆ น้อย ๆ " ล่วงหน้า แน่นอนว่า "JS Parser" จะไม่พบข้อมูลบางอย่างอย่างไม่เป็นทางการมันจะพบได้ตาม VAR, ฟังก์ชั่นและพารามิเตอร์
"JS Parser" ค่อนข้าง "ขี้เกียจ" ก่อนที่จะเรียกใช้รหัสอย่างเป็นทางการจะกำหนดตัวแปรที่ประกาศโดย VAR ให้ไม่ได้กำหนดนั่นคือ var a = undefined; มันจะถือว่าฟังก์ชั่นทั้งหมดเป็นบล็อกรหัสโดยไม่คำนึงถึงว่ามีรหัสมากแค่ไหน พารามิเตอร์จะถูกกล่าวในตัวอย่างในภายหลัง
หลังจากการเตรียมการทั้งหมดเสร็จสิ้น "JS Parser" เริ่มดำเนินการรหัสทีละบรรทัด ตอนนี้มาวิเคราะห์ตัวอย่างที่เราเริ่มต้นและเข้าใจง่ายว่าทำไมมันถึงไม่ได้กำหนด
ลองดูตัวอย่างต่อไปนี้
การแจ้งเตือน (a); var a = 1; การแจ้งเตือน (a); var a = 2; การแจ้งเตือน (a);
มาวิเคราะห์กันหน่อย
"การเตรียม" ครั้งแรก: ตัวแยกวิเคราะห์จะมองหา var
เมื่ออ่านบรรทัดที่สอง A = ไม่ได้กำหนด;
เมื่ออ่านบรรทัดที่สี่ยังคงไม่ได้กำหนด;
การดำเนินการตามบรรทัดต่อบรรทัดของรหัส:
การแจ้งเตือนบรรทัดแรก: ไม่ได้กำหนด
บรรทัดที่สอง a = 1;
บรรทัดที่ 3 การแจ้งเตือน: 1;
การแจ้งเตือนองค์ประกอบที่ห้า: 2
มาดูตัวอย่างด้านล่าง
การแจ้งเตือน (a); var a = 1; การแจ้งเตือน (a); ฟังก์ชั่น a () {แจ้งเตือน (2); } Alert (a); var a = 3; การแจ้งเตือน (a); ฟังก์ชั่น a () {แจ้งเตือน (4); } Alert (a);มาวิเคราะห์กันทีละนิด
ก่อนอื่น "pre-parse": ตัวแยกวิเคราะห์จะมองหาฟังก์ชั่น var;
เมื่ออ่านบรรทัดที่สอง A = ไม่ได้กำหนด;
เมื่ออ่านบรรทัดที่สี่ a = function a () {การแจ้งเตือน (2);} // ฟังก์ชั่นทั้งหมดเป็นบล็อกฟังก์ชันทั้งหมดก่อนที่จะเรียกใช้รหัสอย่างเป็นทางการ เมื่อตัวแปรพบชื่อที่ซ้ำกันมีเพียงตัวแปรเดียวเท่านั้นที่เหลืออยู่ หากตัวแปรและฟังก์ชั่นเป็นชื่อที่ซ้ำกันจะมีเพียงฟังก์ชั่นเท่านั้น
เมื่ออ่านบรรทัดที่หก A = function A () {Alert (2);}
เมื่ออ่านบรรทัดที่แปด a = function a () {แจ้งเตือน (4);}
การดำเนินการตามบรรทัดต่อบรรทัดของรหัส:
การแจ้งเตือนบรรทัดแรก: ฟังก์ชัน A () {Alert (4);}
บรรทัดที่สอง a = 1; // นิพจน์สามารถปรับเปลี่ยนค่า pre-parsed!
บรรทัดที่ 3 การแจ้งเตือน: 1;
ฟังก์ชั่นบรรทัดที่สี่ไม่ได้เรียกว่าข้าม;
การแจ้งเตือนองค์ประกอบที่ห้า: 1;
บรรทัดที่หก a = 3;
บรรทัด 7 การแจ้งเตือน: 3
ฟังก์ชั่นบรรทัดที่แปดไม่ได้เรียกว่าข้าม;
บรรทัด 9 การแจ้งเตือน: 3
ดังแสดงในรูป:
ดูตัวอย่างต่อไป:
var a = 1; ฟังก์ชั่น fn1 () {แจ้งเตือน (a); // undefined var a = 2;} fn1 (); การแจ้งเตือน (a); // 1"การเตรียม" ครั้งแรก: ตัวแยกวิเคราะห์จะมองหาฟังก์ชั่น VAR
เมื่ออ่านบรรทัดแรก A = ไม่ได้กำหนด;
เมื่ออ่านบรรทัดที่สอง fn1 = ฟังก์ชั่น fn1 () {แจ้งเตือน (2); var a = 2;}
การดำเนินการตามบรรทัดต่อบรรทัดของรหัส: บรรทัดแรก A = 1;
การเรียกใช้ฟังก์ชันบรรทัดที่หกป้อนขอบเขตฟังก์ชันและยังคงเป็นค่า pre-parse ในขอบเขตฟังก์ชันจากนั้นเรียกใช้งานทีละบรรทัด
เตรียมภายในฟังก์ชั่น: a = ไม่ได้กำหนด;
การดำเนินการ: แจ้งเตือน: ไม่ได้กำหนด;
a = 2; // A ในเวลานี้เป็นเพียงขอบเขตของฟังก์ชันและจะไม่ส่งผลกระทบต่อ A ในโลก
ฟังก์ชั่นถูกดำเนินการและกลับสู่ขอบเขตทั่วโลก
สายเจ็ดแจ้งเตือน: 1;
ดำเนินการต่อ:
var a = 1; ฟังก์ชั่น fn1 () {แจ้งเตือน (a); // 1 a = 2;} fn1 (); การแจ้งเตือน (a); // 2ความแตกต่างเพียงอย่างเดียวระหว่างตัวอย่างข้างต้นคือ A ในฟังก์ชั่นไม่มี VAR และวิเคราะห์เฉพาะประเด็นสำคัญ
ในการแจ้งเตือนบรรทัดที่สาม (a) ในขอบเขตฟังก์ชันเนื่องจากไม่มี var a ในฟังก์ชั่น "ตัวแยกวิเคราะห์" จะมองหาขอบเขตระดับบนของขอบเขตของฟังก์ชัน (การกำหนดความสัมพันธ์ระดับบนและระดับล่างขึ้นอยู่กับขอบเขตของฟังก์ชันที่สร้างขึ้น ในเวลานี้ระดับบนของฟังก์ชั่นคือขอบเขตทั่วโลก ในขอบเขตทั่วโลก A = 1 ดังนั้นในเวลานี้การแจ้งเตือนบรรทัดที่สาม: 1 และจากนั้นบรรทัดที่สี่, A = 2 กำหนดค่ายังคงไม่มี A ในขอบเขตฟังก์ชันดังนั้นค้นหาในขอบเขตระดับบนนั่นคือขอบเขตทั่วโลก
จุดนี้จะต้องเข้าใจอย่างชัดเจนและให้ความสนใจกับความแตกต่างระหว่าง VAR หรือไม่
ต่อไป:
var a = 1; ฟังก์ชั่น fn1 (a) {แจ้งเตือน (a); // undefined a = 2; } fn1 (); การแจ้งเตือน (a); // 1ความแตกต่างระหว่างตัวอย่างนี้กับตัวอย่างก่อนหน้านี้คือมีพารามิเตอร์เพิ่มเติม ฟังก์ชั่นของพารามิเตอร์เทียบเท่ากับตัวแปรท้องถิ่นนั่นคือจะมี var a = undefined ใน pre-parsing ในฟังก์ชัน ดังนั้นการแจ้งเตือนบรรทัดที่สาม: ไม่ได้กำหนดและบรรทัดที่สี่ A = 2 เปลี่ยน A ในขอบเขตฟังก์ชันซึ่งไม่ส่งผลกระทบต่อ A ในบริบทของโลก การแจ้งเตือนบรรทัดที่เจ็ด: 1;
แล้ว:
var a = 1; ฟังก์ชั่น fn1 (a) {แจ้งเตือน (a); // 1a = 2;} fn1 (a); แจ้งเตือน (a); // 1ตัวอย่างนี้ค่อนข้างแตกต่างจากตัวอย่างก่อนหน้านี้ เมื่อฟังก์ชั่นถูกเรียกในบรรทัดที่หกพารามิเตอร์จะถูกส่งผ่านพารามิเตอร์จริง A ของฟังก์ชันบรรทัดที่หกคือ 1 ของตัวแปรทั่วโลก a = 1 เมื่อฟังก์ชั่นถูกดำเนินการบรรทัดที่สอง A = 1 ดังนั้นการแจ้งเตือนบรรทัดที่สาม: 1 และการแจ้งเตือนบรรทัดที่เจ็ด: 1
ให้ความสนใจกับความแตกต่างระหว่างตัวอย่างเหล่านี้และอย่าสับสน
อีกอันหนึ่ง:
var a = 1; ฟังก์ชั่น en () {var a = 2; fn ();} ฟังก์ชัน fn () {alert (a); // 1} en ();ใน FN ไม่ได้ประกาศและคุณต้องใช้ค่าในขอบเขตที่สร้างฟังก์ชัน - มันคือ "สร้าง" ไม่ใช่ "เรียก" ขอบเขตของฟังก์ชั่น
PS: แนวคิดขอบเขตและบริบทใน JavaScript
ขอบเขตและบริบทใน JavaScript นั้นไม่ซ้ำกันกับภาษานี้ขอบคุณส่วนหนึ่งของความยืดหยุ่นที่พวกเขานำมา แต่ละฟังก์ชั่นมีบริบทและขอบเขตตัวแปรที่แตกต่างกัน แนวคิดเหล่านี้ได้รับการสนับสนุนโดยรูปแบบการออกแบบที่ทรงพลังใน JavaScript อย่างไรก็ตามสิ่งนี้ยังนำมาซึ่งความสับสนอย่างมากต่อนักพัฒนา ต่อไปนี้เผยให้เห็นความแตกต่างอย่างเต็มที่ในบริบทและขอบเขตใน JavaScript และวิธีการออกแบบที่หลากหลายใช้
บริบทกับขอบเขต
คำถามแรกที่ต้องชี้แจงคือบริบทและขอบเขตเป็นแนวคิดที่แตกต่างกัน ในช่วงหลายปีที่ผ่านมาฉันสังเกตเห็นว่านักพัฒนาหลายคนมักจะสับสนทั้งสองคำนี้อธิบายอย่างผิด ๆ ว่าเป็นอีกคำหนึ่ง เพื่อความเป็นธรรมคำศัพท์เหล่านี้ทำให้เกิดความสับสนมาก
การโทรแต่ละฟังก์ชั่นมีขอบเขตและบริบทที่เกี่ยวข้อง โดยพื้นฐานแล้วขอบเขตคือการใช้ฟังก์ชั่นและบริบทเป็นอิงตามวัตถุ กล่าวอีกนัยหนึ่งขอบเขตเกี่ยวข้องกับการเข้าถึงตัวแปรทุกครั้งที่มีการเรียกฟังก์ชันและการโทรแต่ละครั้งนั้นเป็นอิสระ บริบทมักจะเป็นค่าของคำหลักนี้การอ้างอิงไปยังวัตถุที่เรียกรหัสปฏิบัติการปัจจุบัน
ข้างต้นคือขอบเขตของ JavaScript ที่แนะนำโดยบรรณาธิการ (แนะนำ) ฉันหวังว่ามันจะเป็นประโยชน์กับคุณ หากคุณมีคำถามใด ๆ โปรดฝากข้อความถึงฉันและบรรณาธิการจะตอบกลับคุณทันเวลา ขอบคุณมากสำหรับการสนับสนุนเว็บไซต์ Wulin.com!