ตีความหรือเรียบเรียง การยก และความเท่าเทียมกัน

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) ขั้นตอนการดำเนินการ:นี่คือโค้ดที่ถูกดำเนินการ

ดังนั้น นี่จะอธิบายสองสิ่ง-

  1. เหตุใดตัวแปรที่ประกาศด้วย var ในการยกจึงส่งคืนไม่ได้กำหนด นี่เป็นเพราะค่าเริ่มต้นที่กำหนดให้กับตัวแปรเหล่านั้น เมื่อเรากำหนดค่าอื่นให้กับพวกเขาหลังจากการประกาศ ค่าของมันจะเปลี่ยนไป
  2. เหตุใดจึงไม่สามารถยก let และ const ได้ นี่เป็นเพราะว่าสิ่งเหล่านั้นอยู่ในโซนตายตัวชั่วคราวและไม่สามารถเข้าถึงได้ และด้วยเหตุนี้จึงทำให้เกิดข้อผิดพลาด

b) การยกฟังก์ชัน

นี่เป็นเรื่องง่ายที่จะเข้าใจหากคุณเข้าใจการยกตัวแปร

เช่นเดียวกับตัวแปร ฟังก์ชันต่างๆ จะถูกยกขึ้น แต่จะมีเพียงคำจำกัดความของฟังก์ชันเท่านั้น ไม่ใช่นิพจน์ของฟังก์ชัน

เหตุใดการกำหนดฟังก์ชันจึงถูกยกขึ้นแต่ไม่แสดงนิพจน์ฟังก์ชัน

โปรดทราบว่าคำจำกัดความของฟังก์ชันได้รับการยกขึ้น

แต่นิพจน์ฟังก์ชันแสดงข้อผิดพลาดประเภทเมื่อพยายามยกขึ้น นี่เป็นเพราะเมื่อมีการประกาศแถบด้วย var เนื่องจากในระหว่างขั้นตอนการสร้างจะมีเฉพาะหน่วยความจำเท่านั้นที่ได้รับการจัดสรรและเริ่มต้นด้วย unknown การพยายามเรียก bar() หมายถึง undefinition() ซึ่งทำให้เกิดข้อผิดพลาดประเภท

3. ความเท่าเทียมกัน

ที่นี่ฉันต้องการชี้ให้เห็นความแตกต่างระหว่างความเสมอภาค (==) และความเสมอภาคที่เข้มงวด (===)

นี่เป็นหนึ่งในแนวคิดที่เข้าใจผิด ผู้คนคิดว่าความแตกต่างระหว่างความเสมอภาคและความเสมอภาคที่เข้มงวดคือความเสมอภาคจะตรวจสอบเฉพาะค่าเท่านั้น แต่ความเสมอภาคที่เข้มงวดจะตรวจสอบค่าและพิมพ์ทั้งสองอย่าง

ความแตกต่างที่แท้จริงระหว่างสิ่งเหล่านี้คือ ด้วยความเท่าเทียมกัน การบังคับ (การแปลงประเภทและไม่การตรวจสอบประเภท) จะได้รับอนุญาตในขณะที่ตรวจสอบค่า และด้วยความเท่าเทียมกันที่เข้มงวด จะไม่อนุญาตให้มีการบังคับ

ดังนั้น 2== '2' จะคืนค่าเป็นจริงหลังจากแปลงประเภท Number เป็นประเภท String

แต่ 2===’2' จะส่งคืนค่าเท็จเนื่องจากไม่มีการแปลงประเภทจาก Number เป็น String หรือในทางกลับกัน

แค่นั้นแหละ!! ขอบคุณที่อยู่ด้วยกันจนจบ นี่เป็นแนวคิดบางส่วนที่ฉันพบว่ามีคนจำนวนมากเข้าใจผิด ฉันจะเผยแพร่ส่วนที่ 2 ของบทความเร็ว ๆ นี้

อ้างอิง

  1. เอกสาร MDN
  2. JIT-คอมไพเลอร์
  3. บทความเกี่ยวกับการชักรอก