สแต็กการเรียก
ดูว่าการเรียกฟังก์ชันถูกติดตามไว้อย่างไร
สแต็กการเรียก เป็นบทเรียน JavaScript Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน JavaScript Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส JavaScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
สแตกการเรียกใช้คืออะไร
สแตกการเรียกใช้คือกลไกที่ JavaScript ใช้ติดตามว่าฟังก์ชันใดกำลังทำงานอยู่และควรส่งค่ากลับไปที่ใด การเรียกใช้ฟังก์ชันแต่ละครั้งจะถูกใส่ไว้ด้านบนสุด และเมื่อทำงานเสร็จจะถูกนำออก
โครงสร้างนี้เป็นแบบ LIFO: เข้าหลัง ออกก่อน
การใส่และนำออกจากสแตก
เมื่อคุณเรียกใช้ฟังก์ชัน เฟรมบนสแตกจะถูกใส่เข้าไป เมื่อฟังก์ชันส่งค่ากลับ เฟรมจะถูกนำออก โปรดสังเกตลำดับของบันทึกเมื่อการเรียกใช้ซ้อนกัน
function first() {
console.log('first start');
second();
console.log('first end');
}
function second() {
console.log('second');
}
first();LIFO ในการทำงานจริง
ฟังก์ชันที่ถูกเรียกใช้ล่าสุดต้องทำงานให้เสร็จก่อนฟังก์ชันที่อยู่ด้านล่างจึงจะทำงานต่อได้ การเรียกใช้ด้านในจะเสร็จก่อน แม้จะเริ่มต้นทีหลังก็ตาม
function a() {
console.log('enter a');
b();
console.log('exit a');
}
function b() {
console.log('enter b');
c();
console.log('exit b');
}
function c() {
console.log('c runs');
}
a();การทำงานตามลำดับหมายถึงการหยุดรอ
JavaScript ทำงาน ทีละอย่าง บนเธรดเดียว ขณะที่สแตกมีเฟรมอยู่ จะไม่มีสิ่งอื่นทำงาน โค้ดแบบทำงานตามลำดับจะ ขัดขวางการทำงานจนกว่าจะเสร็จ
console.log('start');
function busy() {
let sum = 0;
for (let i = 0; i < 1000; i++) sum += i;
return sum;
}
console.log(busy());
console.log('end');ค่าที่ส่งกลับไหลลงด้านล่าง
เมื่อแต่ละเฟรมถูกนำออก ค่าที่ส่งกลับของเฟรมนั้นจะไหลกลับไปยังฟังก์ชันผู้เรียกที่รออยู่ด้านล่างบนสแตก
function square(n) {
return n * n;
}
function sumOfSquares(a, b) {
return square(a) + square(b);
}
console.log(sumOfSquares(3, 4));การเรียกซ้ำทำให้สแตกเติบโต
การเรียกซ้ำแต่ละครั้งจะเพิ่มเฟรมอีกหนึ่งเฟรม สแตกจะขยายตัวจนกว่าจะพบกรณีฐาน จากนั้นจึงคลายกลับทีละเฟรม
function countdown(n) {
if (n === 0) {
console.log('liftoff');
return;
}
console.log(n);
countdown(n - 1);
}
countdown(3);สแตกเต็ม
สแตกมีขนาดจำกัด การเรียกซ้ำที่ไม่มีกรณีฐานจะเพิ่มเฟรมต่อไปจนกระทั่งเอนจินโยน RangeError: ขนาดสแตกการเรียกใช้สูงสุดเกินขีดจำกัด
function endless(n) {
return endless(n + 1);
}
try {
endless(1);
} catch (e) {
console.log(e.name);
}ลำดับการทำงานคาดเดาได้
เนื่องจากสแตกเป็นแบบ LIFO อย่างเคร่งครัดและทำงานตามลำดับ ลำดับของบันทึกจากโค้ดที่ทำงานตามลำดับจึงแน่นอนเสมอ คุณสามารถไล่ลำดับด้วยตนเองได้
function outer() {
console.log(1);
inner();
console.log(3);
}
function inner() {
console.log(2);
}
outer();
console.log(4);จุดที่การทำงานแบบไม่พร้อมกันเข้ามา
สแตกการเรียกใช้ทำงานเฉพาะโค้ดแบบทำงานตามลำดับ ฟังก์ชันอย่าง setTimeout จะส่งต่องานให้สภาพแวดล้อม ซึ่งภายหลังจะนำฟังก์ชันเรียกกลับไปใส่ในคิว ฟังก์ชันเรียกกลับเหล่านั้นจะทำงานได้ก็ต่อเมื่อสแตก ว่าง แล้ว
นี่คือสะพานไปสู่วงจรเหตุการณ์
console.log('A');
setTimeout(() => console.log('B (later)'), 0);
console.log('C');สแตกต้องว่างก่อน
แม้แต่ตัวจับเวลาที่มีความหน่วงเป็นศูนย์มิลลิวินาทีก็ต้องรอให้โค้ดแบบทำงานตามลำดับทั้งหมดเสร็จก่อน ฟังก์ชันเรียกกลับจะทำงานไม่ได้ตราบใดที่ยังมีเฟรมอยู่บนสแตก
console.log('sync 1');
setTimeout(() => console.log('timeout'), 0);
console.log('sync 2');
console.log('sync 3');เหตุใดสแตกการเรียกใช้จึงสำคัญ
ความเข้าใจเรื่องสแตกการเรียกใช้อธิบายได้ว่าทำไมลูปแบบทำงานตามลำดับที่ใช้เวลานานจึงทำให้หน้าเว็บค้าง ทำไมการเรียกซ้ำจึงทำให้สแตกเต็ม และทำไมฟังก์ชันเรียกกลับแบบไม่พร้อมกันจึงทำงานเป็นลำดับสุดท้าย สแตกนี้เป็นพื้นฐานของทุกสิ่งในวงจรเหตุการณ์
function compute() {
return [1, 2, 3].reduce((a, b) => a + b, 0);
}
console.log('before');
console.log(compute());
console.log('after');ตรวจสอบความเข้าใจอย่างรวดเร็ว
สแตกการเรียกใช้ทำตามหลักการจัดลำดับแบบใด
ทบทวน: สแตกการเรียกใช้
คุณได้เรียนรู้แกนหลักของการทำงานของเอนจิน ดังนี้
- สแตกการเรียกใช้ติดตามฟังก์ชันที่กำลังทำงานตามลำดับแบบ LIFO
- JavaScript ใช้เธรดเดียว และโค้ดแบบทำงานตามลำดับจะ ขัดขวางการทำงาน
- การเรียกซ้ำทำให้สแตกเติบโตและอาจทำให้สแตกเต็ม
- ฟังก์ชันเรียกกลับแบบไม่พร้อมกันจะรอจนกว่าสแตกจะว่าง ซึ่งนำไปสู่วงจรเหตุการณ์
คำถามที่พบบ่อย
บทเรียน “สแต็กการเรียก” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “สแต็กการเรียก” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส JavaScript Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส JavaScript Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “สแต็กการเรียก”
ดูว่าการเรียกฟังก์ชันถูกติดตามไว้อย่างไร คุณปฏิบัติ JavaScript Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน JavaScript Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน JavaScript Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “สแต็กการเรียก” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน JavaScript Academy นี้ได้ไหม
ได้ บทเรียน JavaScript Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ