บทความนี้อธิบายถึง JavaScript pre-parsing และเทคนิคที่เกี่ยวข้อง แบ่งปันสำหรับการอ้างอิงของคุณดังนี้:
ตัวแปร
อีกครั้งเริ่มต้นด้วยการเปรียบเทียบข้อผิดพลาดของตัวอย่างเล็ก ๆ สองตัวอย่างนี้
การแจ้งเตือน (Y1); // รหัสเซ็กเมนต์ 1var y1 = 'dddd'; แจ้งเตือน (y2); // รหัสเซ็กเมนต์ 2 // การแจ้งเตือน (typeof y2); y2 = 'xxxxx';
ก่อนอื่นลองคิดดูว่าทำไมคน ๆ หนึ่งจึงไม่ได้กำหนดและอีกคนหนึ่งโยนข้อผิดพลาดของตัวแปรที่ไม่ได้กำหนด - ก่อนอื่นให้ดูที่กระบวนการแยกวิเคราะห์ JavaScript
ก่อนกระบวนการดำเนินการ JavaScript จะทำเหตุการณ์ "การเตรียมการ" เอ็นจิ้นการแยกวิเคราะห์ดำเนินการสร้างตัวแปร VAR ทั้งหมดที่ระดับบล็อกและให้ค่าเริ่มต้น: ไม่ได้กำหนด ด้วยวิธีนี้เหตุผลที่ตัวอย่างแรกปรากฏขึ้นที่ไม่ได้กำหนดนั้นชัดเจน
ดังนั้นรหัสแรกจึงเทียบเท่ากับ
var y1; การแจ้งเตือน (typeof y1); // ตามธรรมชาติค่าของมันคือ undefinedy1 = 'dddd';
ทำไมรหัสชิ้นที่สองถึงทำผิดอีกครั้ง? มันไม่ได้เป็นของขั้นตอน "pre-parse" อีกต่อไป (ที่นี่ฉันคิดว่าเบราว์เซอร์ทำเพียงสองสิ่งเมื่อพบแท็กสคริปต์: pre-parse และการดำเนินการซึ่งจริง ๆ แล้วไม่ใช่แค่สองสิ่งนี้) อย่างไรก็ตามในขั้นตอนการดำเนินการเหตุผลในการโยนข้อผิดพลาดคือ JS ไม่ทราบสถานะของ Y2 ในสถานะเซ็กเมนต์การดำเนินการ (ไม่มีข้อมูลของ Y2 ถูกบันทึกไว้ในขั้นตอนก่อนการเสียชีวิต) และแน่นอนว่ามันส่งข้อมูลข้อผิดพลาดที่ไม่ได้กำหนด ปัญหาอีกประการหนึ่งเกี่ยวข้องกับที่นี่: JS เป็นภาษาที่อ่อนแอและสามารถใช้ตัวแปรได้โดยไม่ต้องมีคำจำกัดความดังนั้นทำไมมันจึงถูกโยนลงที่นี่เป็นข้อผิดพลาดคำจำกัดความ?
มีเหตุผลที่จะเกิดขึ้นเสมอ JavaScript มีคุณสมบัติแปลก ๆ มากมายและมีตัวแปรที่อ่านและเขียนไม่สม่ำเสมอ ตัวแปรที่ไม่ได้กำหนดนั้นสามารถเขียนได้เท่านั้นและไม่สามารถอ่านได้ สามารถเขียนอะไรได้บ้าง? ทุกคนคุ้นเคยกับวิธีการเขียนนี้:
y2 = 'การสอบ'; // ก่อนที่การดำเนินการนิยามจะปรากฏขึ้น (เช่นก่อนที่จะไม่มีขอบเขตของตัวเอง) การดำเนินการนี้จะพิจารณารหัสนี้เพื่อกำหนดตัวแปรทั่วโลกลงทะเบียนคุณสมบัติ Y2 บนหน้าต่างและกำหนดให้สอบเพื่อสอบ
แต่เมื่ออ่านมันเครื่องยนต์ JS ไม่สามารถหาข้อมูลที่เกี่ยวข้องเกี่ยวกับเรื่องนี้ได้ดังนั้นมันจึงทำหน้าที่กับอารมณ์ของตัวเองและทำผิดพลาดที่ไม่ได้กำหนดโดยไม่ลังเล นี่คือกฎของเกม JS และทำไมคุณถึงได้รับประเภทของมัน? จดจำการดำเนินการของ JS ในวัตถุ หากคุณเข้าถึงวัตถุที่ไม่มีอยู่มันจะไม่ได้กำหนด (เนื่องจากเป็นแอตทริบิวต์ของวัตถุหน้าต่าง)
หมายเหตุ: มีความจำเป็นที่จะต้องแยกแยะความแตกต่างที่นี่ว่าตัวแปรอ่านและเขียนที่ไม่สม่ำเสมอใช้สำหรับตัวแปรเท่านั้นและคุณสมบัติทั้งหมดของวัตถุจะอ่าน คุณสมบัตินี้ไม่มีอยู่ หากไม่มีอยู่มันจะไม่ได้กำหนด
สรุปแล้ว
ณ จุดนี้ความคิดของฉันเป็นผล: มีความคล้ายคลึงกันบางอย่างในการดำเนินการเขียนของตัวแปรและวัตถุ อย่างไรก็ตามแต่ละชุดมีกฎของตัวเองสำหรับการดำเนินการอ่าน ด้วยเหตุนี้จึงพบปัญหาข้างต้น
ด้วยวิธีนี้คำถามต่อไปนี้ควรตอบได้ง่าย
if (! ('a' ในหน้าต่าง)) {var a = 1;} การแจ้งเตือน (a);การทำงาน
เพื่อขยายฟังก์ชั่น โปรดจำไว้ว่าการตั้งค่าล่วงหน้าที่กล่าวถึงข้างต้น ในการตั้งค่าล่วงหน้าของ JavaScript นอกเหนือจากการนิยามล่วงหน้าของตัวแปร VAR มันยังรวมถึงการแยกนิยามของฟังก์ชันดังนั้นฟังก์ชันสามารถกำหนดได้ทุกที่ในสคริปต์และเรียกว่าทุกที่ ไม่ จำกัด ก่อนหน้านี้
อย่างไรก็ตามวิธีการนิยามของฟังก์ชั่นรวมถึงวิธีการนิยามตัวอักษรโดยใช้วิธีการของ VAR ในการประกาศฟังก์ชั่น ดูด้านล่าง
การแจ้งเตือน (typeof y3); // ผลลัพธ์? var y3 = function () {console.log ('1'); -โปรดจำไว้ว่าข้อตกลงนี้: การโทรจะต้องปรากฏขึ้นหลังจากการประกาศ ทำไม หากคุณเข้าใจข้างต้นคำตอบที่นี่ชัดเจนจริง ๆ เมื่อ pre-parsing var เอ็นจิ้น JavaScript จะให้ค่าเริ่มต้นที่ไม่ได้กำหนด ด้วยวิธีนี้ถ้าเราเรียกมันก่อนการประกาศของมันเอ็นจิ้น JavaScript ยังไม่ได้รับค่าที่แท้จริงมันจะรายงานข้อผิดพลาดของ "XXX ไม่ใช่ฟังก์ชัน" ตามธรรมชาติ สิ่งนี้ยังชี้แจงว่าทำไมการประกาศฟังก์ชั่นทั้งสองจึงเกี่ยวข้องกับคำสั่งของการประกาศและการโทรและอีกข้อหนึ่งไม่มีข้อ จำกัด ดังกล่าว
สรุปแล้ว
มันเป็นฟังก์ชั่นผลของการดำเนินการ JS และการปรับเปลี่ยนแบบไดนามิกและยังคงเป็นไปตามกฎการวิเคราะห์ก่อนของตัวแปร (เมื่อแจ้งเตือนด้านบนมันไม่ได้รับข้อมูลของฟังก์ชั่นตัวอักษร)
เกิดอะไรขึ้นถ้ามันเป็นส่วนผสมของสอง ดูสิ่งต่อไปนี้มีทั้งตัวแปรและฟังก์ชั่นสำหรับ Y4
การแจ้งเตือน (typeof y4); // ผลลัพธ์? ฟังก์ชั่น y4 () {console.log ('y4')} var y4;เนื่องจาก JavaScript มีลำดับความสำคัญสูงในการเตรียมล่วงหน้า Y4 จึงเป็นประเภทฟังก์ชันตามธรรมชาติ แต่หลังจากที่ได้รับมอบหมาย Y4 (เครื่องยนต์ JS อยู่ในกระบวนการดำเนินการ) การดำเนินการที่ได้รับมอบหมายให้ JS จะแทนที่การประกาศฟังก์ชั่น ดังนั้น:
การแจ้งเตือน (typeof y5); var y5 = 'angle'; ฟังก์ชั่น y5 () {console.log ('ผี'); } Alert (Y5);ผลลัพธ์การแจ้งเตือนครั้งแรกคือฟังก์ชั่นเนื่องจากอยู่ที่ด้านบนของกระบวนการดำเนินการ JS ครั้งที่สองเมื่อเปลี่ยนชื่อการแจ้งเตือนค่าของมันถูกเขียนใหม่เป็น 5 (อย่าสับสนกับตำแหน่งนิยามของฟังก์ชั่นด้านล่าง)
เมื่อนึกถึงการวิเคราะห์และการดำเนินการของ JS ฉันรู้ว่าฉันรู้ทันทีว่าคำตอบสำหรับคำถามมากมายโผล่ขึ้นมาตามธรรมชาติ ดังที่ผู้เขียนบทความนั้นกล่าวว่า "เมื่อคุณเข้าใจแนวคิดของสภาพแวดล้อมการดำเนินการการโทรวัตถุการปิดขอบเขตคำศัพท์และขอบเขตขอบเขตปรากฏการณ์มากมายในภาษา JS สามารถแก้ไขได้ง่าย"
เมื่อมองย้อนกลับไปตอนนี้แม้ในภาษาที่เหลือเชื่อนี้มีหลายเหตุผลที่สามารถย้อนกลับไปได้
วิธีการตัดสินพารามิเตอร์ที่ดีขึ้น
หลังจากพูดคุยกันมากมายข้างต้นมันจะใกล้ชิดกับการพัฒนาจริงมากขึ้นได้อย่างไร? ตั้งแต่การอ่านและเขียนของ JavaScript เราจะหลีกเลี่ยงการตัดสินพารามิเตอร์โดยไม่ต้องรายงานข้อผิดพลาดได้อย่างไร
เช่น:
ถ้า (cusvar) {// การตัดสินที่นี่เป็นปัญหาโดยนัย -วิธีการเข้มงวดมากขึ้น
if (window ['cusvar']) {// ตรวจสอบให้แน่ใจว่าไม่ได้รายงานข้อผิดพลาด // หรือการตัดสินดังกล่าวเป็น window.cusvar | typeof cusvar! == 'undefined' // work}ในที่สุดก็มีการเพิ่มแบบทดสอบเล็ก ๆ อีกครั้ง (เข้าใจการแยกการเตรียมการก่อนและการดำเนินการ)
var y7 = 'test'; ฟังก์ชั่น fun1 () {แจ้งเตือน (y7); var y7 = 'เพศ';} fun1 ();สำหรับข้อมูลเพิ่มเติมเกี่ยวกับเนื้อหาที่เกี่ยวข้องกับ JavaScript โปรดตรวจสอบหัวข้อของไซต์นี้: "สรุปเอฟเฟกต์และเทคนิคการสลับ JavaScript", "สรุปทักษะอัลกอริธึมการค้นหา JavaScript", "สรุปผลการสรุปและเทคนิคการสรุปของ JavaScript ของ JavaScript อัลกอริทึมและเทคนิคการสำรวจ JavaScript "และ" สรุปการใช้งานทางคณิตศาสตร์ JavaScript "
ฉันหวังว่าบทความนี้จะเป็นประโยชน์กับการเขียนโปรแกรม JavaScript ของทุกคน