เหตุใด JavaScript จึงเพิ่มตัวแปร


95

เหตุใด JavaScript จึงเพิ่มตัวแปร

อะไรคือเหตุผลของนักออกแบบเมื่อพวกเขาตัดสินใจที่จะใช้งานชักรอก? มีภาษายอดนิยมอื่น ๆ ที่ทำเช่นนี้หรือไม่?

โปรดระบุลิงค์ที่เกี่ยวข้องไปยังเอกสารและ / หรือบันทึก


7
ฉันสงสัยว่าในตอนนี้มันเป็นเรื่องประวัติศาสตร์และฉันสงสัยอย่างจริงจังว่ามันเป็นอย่างอื่นที่ไม่ใช่ "ความสะดวกในการนำไปใช้" แต่เดิม
Dave Newton

4
จริงๆแล้วขอให้ Brendan Eich ดูเหมือนว่าเขาจะตอบสนองได้ดีทีเดียว
Felix Kling

23
คำถามนี้ไม่สร้างสรรค์ได้อย่างไร
Francisc

19
@Francisc ยินดีต้อนรับสู่ Stack Overflow ที่คุณสามารถถามได้ทั้งหมดคือการย้ายdivใน jQuery
Xlaudius

21
นี่เป็นคำถามที่สำคัญมาก ควรได้รับอนุญาต ไม่ใช่เหยื่อเปลวไฟ การชักรอกเป็นหนึ่งในองค์ประกอบหลักของการทำความเข้าใจว่า JavaScript ทำงานอย่างไรและ "ทำไม" เป็นคำถามที่ถูกต้องซึ่งกล่าวถึงในตำราเรียนส่วนใหญ่ของภาษา ไม่เป็นไรที่ผู้คน Stack Overflow กระทืบคำถามของผู้คนเช่นนี้อย่างต่อเนื่อง
bearvarine

คำตอบ:


55

ตามที่ Stoyan Stefanov อธิบายไว้ในหนังสือ "JavaScript Patterns" การชักรอกเป็นผลมาจากการใช้งานตัวแปล JavaScript

การตีความโค้ด JS ดำเนินการในสองรอบ ในระหว่างการส่งครั้งแรกล่ามจะประมวลผลการประกาศตัวแปรและฟังก์ชัน

รหัสผ่านที่สองคือขั้นตอนการเรียกใช้โค้ดจริง ล่ามจะประมวลผลนิพจน์ฟังก์ชันและตัวแปรที่ไม่ได้ประกาศ

ดังนั้นเราสามารถใช้แนวคิด "ชักรอก" เพื่ออธิบายพฤติกรรมดังกล่าว


15
โดยส่วนตัวแล้วไม่ชอบคำว่าชักรอก มันทำให้การแทนค่าเป็นเท็จว่าการประกาศตัวแปรและฟังก์ชันถูกยกขึ้นไปด้านบนสุดของขอบเขตปัจจุบันอย่างน่าอัศจรรย์เมื่อในความเป็นจริงตัวแปล JS ตามที่คุณกล่าวถึงจะสแกนซอร์สโค้ดเพื่อหาการเชื่อมโยงแล้วรันโค้ด
contactmatt

ตอนนี้ฉันเข้าใจแล้วว่าทำไมภาษาที่เข้าใจผิดมากที่สุดของ JS ฉันไม่เห็นสิ่งนี้ในบทช่วยสอนใด ๆ และสับสนกับการชักรอก (และการไหลระหว่างพรีเตอร์)
Swapnil Patwa

18
เอ่อนี่ไม่ได้อธิบายเหตุผลจริงๆ ล่ามแบบ single-pass (ซึ่งจะไม่นำไปสู่การชักรอก) จะง่ายกว่ามาก - เหตุใดนักออกแบบจึงเลือกใช้สองใบ
Bergi

1
สิ่งนี้ไม่ได้อธิบายว่าเหตุใดตัวแปรจึงถูกยกขึ้นโดยเฉพาะ ฟังก์ชั่นสมเหตุสมผลตัวแปรไม่ (ในกรณีส่วนใหญ่) - ฉันเชื่อว่ามันเป็นจุดบกพร่อง
Josh M.

1
Josh M. มีการระบุอย่างกว้างขวางมากฉันไม่คิดว่านี่เป็น "ข้อบกพร่อง" ... (ฉันยอมรับว่าคำตอบนี้ไม่ได้ตอบเหตุผลจริงๆ)
Jonas Wilms

11

ผู้สร้าง JS Brendan Eich เคยกล่าวไว้ (บน Twitter) :

"var hoisting จึงเป็น [an] ผลลัพธ์ที่ไม่ได้ตั้งใจของการยกฟังก์ชันไม่มีขอบเขตการบล็อก [และ] JS ในฐานะงานเร่งด่วนในปี 1995"

เขายังอธิบายว่า…

"function hoisting ช่วยให้สามารถแยกโปรแกรมจากบนลงล่าง" let rec "ได้ฟรีโทรก่อนประกาศ; var hoisting ติดแท็ก"

Brendan Eich

มีภาษายอดนิยมอื่น ๆ ที่ทำเช่นนี้หรือไม่?

ฉันไม่รู้ภาษายอดนิยมอื่น ๆ ที่ยกตัวแปรในลักษณะเดียวกัน ฉันคิดว่าแม้แต่ ActionScript ซึ่งเป็นการนำ ECMAScript อื่นที่ใช้ในการพัฒนา Flash - ไม่ได้ใช้การชักรอก นี่เป็นที่มาของความสับสนและความยุ่งยากสำหรับนักพัฒนาที่คุ้นเคยกับภาษาอื่น ๆ ที่กำลังเรียนรู้ JavaScript

UPDATE: จากความคิดเห็นที่งูใหญ่มีพฤติกรรม hoisting ตัวแปรที่คล้ายกัน


2
ให้ +1 เนื่องจากนี่เป็นคำตอบเดียวที่พยายามตอบคำถามโดยตรง
Damon

1
ขอบคุณสำหรับคำตอบนี้ ฉันเห็นด้วยกับ @Damon!
codingbryan

1
อีกหนึ่งภาษายอดนิยมที่มีการยกตัวแปรคือ Python: stackoverflow.com/q/63337235/2326961
Maggyero

2

เนื่องจากตัวแปลจาวาสคริปต์แปลรหัสเป็นสองรอบ

  1. การเติมโค้ด / การรวบรวม:
  2. การดำเนินการรหัส:

ในรอบที่ 1 การประกาศตัวแปรและฟังก์ชันทั้งหมดจะถูกนำไปที่ด้านบนสุดของขอบเขตฟังก์ชันที่กำลังดำเนินการซึ่งจะช่วยในการสร้างvariableObjectsสำหรับexecution contextการทำงานแม้กระทั่งก่อนที่การดำเนินการของมัน

ในระยะที่ 2 การกำหนดค่าคำสั่งรหัสและการเรียกใช้ฟังก์ชันจะเกิดขึ้นทีละบรรทัดในลักษณะที่คาดไว้

คุณอ่านรายละเอียดเพิ่มเติมได้เล็กน้อย ที่นี่

มันจะทำให้คุณเป็นพฤติกรรมรอบภาพที่ดีขึ้นรอบ ๆlet, constและclassการประกาศยังมีความสำคัญต่อไปนี้มันระหว่างตัวแปรและฟังก์ชั่น


1
คุณบอกเป็นนัยว่าเป็นผลมาจากตัวเลือกการออกแบบหรือไม่? ถ้าเป็นเช่นนั้นคุณควรระบุให้ชัดเจนในคำตอบของคุณ แต่การอ่านคำตอบของ Brendan Eich อาจเป็นลักษณะที่ต้องการขึ้นอยู่กับว่าคุณตีความประโยคสุดท้ายอย่างไร บรรทัดล่างฉันยังไม่รู้ว่าทำไมแน่นอน
Bombinosh
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.