JavaScript: Call stack dan keajaiban ukurannya

Halo, orang Khabrov!





Sebagian besar pengembang yang telah menggunakan rekursi untuk menyelesaikan masalah mereka telah melihat kesalahan ini:





 RangeError: Maximum call stack size exceeded. 
      
      



Tetapi tidak setiap pengembang memikirkan tentang apa arti "call stack size" dan apa ukuran ini? Dan bagaimana mengukurnya?





Saya pikir mereka yang bekerja dengan bahasa yang secara langsung bekerja dengan memori dapat dengan mudah menjawab pertanyaan ini, tetapi seorang pengembang front-end biasanya menanyakan dirinya sendiri pertanyaan seperti itu untuk pertama kalinya. Nah, mari kita coba mencari tahu!





Banyak orang percaya bahwa browser membatasi kami dengan tepat dalam jumlah panggilan, tetapi tidak demikian. Pada artikel ini, saya akan menunjukkan kepada Anda dengan contoh sederhana bagaimana sebenarnya itu bekerja.





Apa yang kamu bicarakan, penulis?

Untuk artikel ini, penting untuk memahami konsep seperti Execution Stack, Execution Context. Jika Anda tidak tahu apa itu, maka saya menyarankan Anda untuk membacanya. Sumber daya ini sudah memiliki cukup artikel bagus tentang topik ini. Contoh -  https://habr.com/ru/company/ruvds/blog/422089/





Kapan kesalahan ini terjadi?

Mari kita ambil contoh sederhana - sebuah fungsi yang secara rekursif memanggil dirinya sendiri.





const func = () => {
    func();
}
      
      



Jika kita mencoba memanggil fungsi seperti itu, maka kita akan melihat kesalahan di konsol / terminal, yang saya sebutkan di atas.





Tetapi bagaimana jika Anda melihat berapa kali fungsi itu dijalankan sebelum kesalahan terjadi?





Chrome DevTools 2021. . .





:





let i = 0;

const func = () => {
  i++;

  func();
};

try {
  func();
} catch (e) {
  //          
  console.log(i);
}
      
      



13914. , , , 14 .





, . , :





let i = 0;

const func = () => {
  let someVariable = i + 1;
  i++;

  func();
};

try {
  func();
} catch (e) {
  console.log(i);
}
      
      



, , someVariable



  . , , . 12523 . , . , , , .





? ? , , ?!





- . . , , - . -, , , ? , ? : 





let i = 0;

const func = () => {
  let a = i + 1;
  let b = a + 1;
  let c = b + 1;
  let d = c + 1;
  let e = d + 1;
  i++;

  func();
};

try {
  func();
} catch (e) {
  console.log(i);
}
      
      



, . , - 8945. , . , . , .





Execution Stack (Call Stack) - . . , . , , . . , , .





. -   . - , . Call Stack (Execution Stack), , Execution Context - ( this). , , "" , , . Execution Context, , . "" , .





. , ? , , Chrome?





-

, , (, ). Execution Stack, . N, K. X.





- , ( ) :





FunctionSize = N + K * SizeOfVar

SizeOfVar - , .





, , , :





X = (N + 0 * SizeOfVar) * 13914 = N * 13914

, , , .





X = (N + 5 * SizeOfVar) * 8945

- . , .





N * 13914 = (N + 5 * SizeOfVar) * 8945

. - N SizeOfVar. N - , SizeOfVar? , , , "number", , , .





- " JavaScript 64- . 8 , 64/8 = 8 ." - . 8 . , N.





N * 13914 = (N + 5 * 8) * 8945

:





N * 13914 = N * 8945 + 40 * 8945

N, : N 72. 72 .





, N = 72 , , Chrome ... 1002128 . . , .





- , , ? , , 7 'number'. 





: , (72 + 7 * 8) , 128. 1002128 128 ... 7829! , 7829 !  ...





. 3. , . , , , - . - .



, , ExecutionStack Chrome 72 , - .



!





. .  . 45606 . 39905 . NodeJS Chrome . JavaScript. 





?

, Object? 





let i = 0;

const func = () => {
  const a = {
    key: i + 1,
  };
  i++;

  func();
};

try {
  func();
} catch (e) {
  console.log(i);
}
      
      



. 12516. , . JS' - . , .





? ? *?

, . , . , , . , .





:

  • .





  • .





  • "" , .





  • .





: "number" , , ?








All Articles