ตีความหรือเรียบเรียง การยก และความเท่าเทียมกัน
1. ตีความหรือเรียบเรียง
นี่คือสิ่งที่หลายคนยังคงสับสน หากคุณถามคำถาม “JavaScript ถูกตีความหรือคอมไพล์หรือไม่?” คุณจะได้รับคำตอบที่แตกต่างออกไป ก่อนอื่น เรามาทำความเข้าใจกันก่อนว่าจริงๆ แล้วการตีความและเรียบเรียงหมายถึงอะไร
ภาษาที่เรียบเรียง
กล่าวกันว่าภาษาจะถูกคอมไพล์เมื่อมีการแปลโปรแกรมทั้งหมดเป็นรหัสเครื่องเป็นครั้งแรก จากนั้นจึงดำเนินการรหัสเครื่องที่แปลแล้ว
ภาษาที่ตีความ
กล่าวกันว่าภาษาจะถูกตีความเมื่อการแปลเกิดขึ้นทีละบรรทัดระหว่างการดำเนินการ
จาวาสคริปต์ถูกตีความในตอนแรกอย่างหมดจด
ภาษาที่ตีความไม่จำเป็นต้องใช้เวลาเพิ่มเติมสำหรับขั้นตอนการคอมไพล์ ซึ่งทำให้เหมาะสำหรับเว็บ เนื่องจาก JavaScript เคยเป็นภาษาที่ตีความล้วนๆ
แต่สิ่งนี้ยังทำให้ JavaScript ช้ามากด้วย ทำไม เนื่องจากไม่มีขั้นตอนการคอมไพล์ทุกครั้งที่พบการวนซ้ำระหว่างการดำเนินการ จึงถูกตีความในแต่ละครั้งที่ทำให้โค้ดทำงานช้า หากมีขั้นตอนการคอมไพล์ ลูปจะไม่ถูกแปลในแต่ละครั้งและโค้ดจะทำงานเร็วขึ้น
นอกจากนี้ ในภาษาที่คอมไพล์ในขณะที่การแปลเสร็จก่อนดำเนินการ คอมไพเลอร์นอกเหนือจากการแปลโค้ดยังทำการปรับปรุงบางอย่างเพื่อให้สามารถทำงานได้เร็วขึ้น
JavaScript เป็นภาษาที่คอมไพล์ด้วย JIT
คอมไพล์ด้วย JIT หมายถึงอะไร
ภาษาที่คอมไพล์ JIT (Just-in-time) ใช้คุณสมบัติของทั้งภาษาที่แปลและภาษาที่คอมไพล์
ขณะนี้เอ็นจิ้น JavaScript มีจอภาพแล้ว จอภาพจะรันโปรแกรมทั้งหมดผ่านล่ามก่อน หากโค้ดบรรทัดเดียวกันทำงานสองสามครั้ง โค้ดจะถูกระบุว่าเป็น warm และหากรันหลายครั้งก็จะมีป้ายกำกับว่าร้อน
วอร์มโค้ดถูกส่งไปเพื่อรับการคอมไพล์โดย คอมไพเลอร์พื้นฐาน ซึ่งจะคอมไพล์โค้ดแล้วจัดเก็บไว้เพื่อให้สามารถใช้งานได้เมื่อโค้ดบรรทัดเดียวกันทำงานอีกครั้ง คอมไพเลอร์มีการปรับปรุงประสิทธิภาพเพียงเล็กน้อยที่นี่
เมื่อวอร์มโค้ดเริ่มทำงานมากขึ้นไปอีก มันจะถูกส่งไปยัง คอมไพเลอร์ที่เพิ่มประสิทธิภาพ ซึ่งจะสร้างโค้ดนั้นในเวอร์ชันที่เร็วยิ่งขึ้น
ดังนั้นจึงปลอดภัยที่จะกล่าวว่า JavaScript ไม่ได้ถูกตีความหรือคอมไพล์อย่างหมดจด แต่เป็นภาษาที่คอมไพล์ด้วย JIT
2. การยก
ตามการยกเอกสาร MDN หมายถึง -
Hoisting คือการที่เราสามารถอ้างถึงตัวแปรหรือฟังก์ชันก่อนการประกาศตัวแปรโดยไม่ได้รับข้อยกเว้นใดๆ
ก) การยกแบบแปรผัน
หลายๆ คนบอกว่าตัวแปรที่ประกาศด้วย var จะถูกยกไปไว้เหนือขอบเขต เนื่องจากตัวแปรดังกล่าวสามารถใช้ได้ก่อนที่จะประกาศ แต่จริงๆ แล้วหมายความว่าอย่างไร? ตัวแปรถูกยกขึ้นเกินขอบเขตจริงหรือไม่ จะเกิดอะไรขึ้นกับเลท? เหตุใดตัวแปรจึงประกาศด้วย la not get hoisted?
เอ็นจิ้น JavaScript รันโค้ดสองครั้ง -
i) ขั้นตอนการสร้าง:นี่คือตัวแปรที่ได้รับการจัดสรรหน่วยความจำ จนถึง ES5 ตัวแปรถูกเตรียมใช้งานด้วย unknownแต่ด้วยฟีเจอร์ ES6 (let, const ฯลฯ) ตัวแปรจะไม่ถูกเตรียมใช้งาน แต่จะถูกตั้งค่าเป็นโหมดพิเศษที่เรียกว่า temporal dead โซนซึ่งตัวแปรยังคงอยู่และไม่สามารถเข้าถึงได้จนกว่าจะได้รับการกำหนดค่า
ii) ขั้นตอนการดำเนินการ:นี่คือโค้ดที่ถูกดำเนินการ
ดังนั้น นี่จะอธิบายสองสิ่ง-
- เหตุใดตัวแปรที่ประกาศด้วย var ในการยกจึงส่งคืนไม่ได้กำหนด นี่เป็นเพราะค่าเริ่มต้นที่กำหนดให้กับตัวแปรเหล่านั้น เมื่อเรากำหนดค่าอื่นให้กับพวกเขาหลังจากการประกาศ ค่าของมันจะเปลี่ยนไป
- เหตุใดจึงไม่สามารถยก let และ const ได้ นี่เป็นเพราะว่าสิ่งเหล่านั้นอยู่ในโซนตายตัวชั่วคราวและไม่สามารถเข้าถึงได้ และด้วยเหตุนี้จึงทำให้เกิดข้อผิดพลาด
b) การยกฟังก์ชัน
นี่เป็นเรื่องง่ายที่จะเข้าใจหากคุณเข้าใจการยกตัวแปร
เช่นเดียวกับตัวแปร ฟังก์ชันต่างๆ จะถูกยกขึ้น แต่จะมีเพียงคำจำกัดความของฟังก์ชันเท่านั้น ไม่ใช่นิพจน์ของฟังก์ชัน
เหตุใดการกำหนดฟังก์ชันจึงถูกยกขึ้นแต่ไม่แสดงนิพจน์ฟังก์ชัน
โปรดทราบว่าคำจำกัดความของฟังก์ชันได้รับการยกขึ้น
แต่นิพจน์ฟังก์ชันแสดงข้อผิดพลาดประเภทเมื่อพยายามยกขึ้น นี่เป็นเพราะเมื่อมีการประกาศแถบด้วย var เนื่องจากในระหว่างขั้นตอนการสร้างจะมีเฉพาะหน่วยความจำเท่านั้นที่ได้รับการจัดสรรและเริ่มต้นด้วย unknown การพยายามเรียก bar() หมายถึง undefinition() ซึ่งทำให้เกิดข้อผิดพลาดประเภท
3. ความเท่าเทียมกัน
ที่นี่ฉันต้องการชี้ให้เห็นความแตกต่างระหว่างความเสมอภาค (==) และความเสมอภาคที่เข้มงวด (===)
นี่เป็นหนึ่งในแนวคิดที่เข้าใจผิด ผู้คนคิดว่าความแตกต่างระหว่างความเสมอภาคและความเสมอภาคที่เข้มงวดคือความเสมอภาคจะตรวจสอบเฉพาะค่าเท่านั้น แต่ความเสมอภาคที่เข้มงวดจะตรวจสอบค่าและพิมพ์ทั้งสองอย่าง
ความแตกต่างที่แท้จริงระหว่างสิ่งเหล่านี้คือ ด้วยความเท่าเทียมกัน การบังคับ (การแปลงประเภทและไม่การตรวจสอบประเภท) จะได้รับอนุญาตในขณะที่ตรวจสอบค่า และด้วยความเท่าเทียมกันที่เข้มงวด จะไม่อนุญาตให้มีการบังคับ
ดังนั้น 2== '2' จะคืนค่าเป็นจริงหลังจากแปลงประเภท Number เป็นประเภท String
แต่ 2===’2' จะส่งคืนค่าเท็จเนื่องจากไม่มีการแปลงประเภทจาก Number เป็น String หรือในทางกลับกัน
แค่นั้นแหละ!! ขอบคุณที่อยู่ด้วยกันจนจบ นี่เป็นแนวคิดบางส่วนที่ฉันพบว่ามีคนจำนวนมากเข้าใจผิด ฉันจะเผยแพร่ส่วนที่ 2 ของบทความเร็ว ๆ นี้