JavaScript: Call stack and the magic of its size

Hello, Khabrovites!





Most developers who have used recursion to solve their problems have seen this error:





 RangeError: Maximum call stack size exceeded. 
      
      



But not every developer thought about what "call stack size" means and what is this size? And how to measure it?





I think those who work with languages ​​that directly work with memory can easily answer this question, but a typical front-end developer is most likely asking himself such questions for the first time. Well, let's try to figure it out!





Many people believe that the browser limits us precisely in the number of calls, but this is not the case. In this article, I'll show you with simple examples how it actually works.





What are you talking about, author?

For the article, it is important to understand concepts such as Execution Stack, Execution Context. If you do not know what it is, then I advise you to read about it. This resource has already had enough good articles on this topic. Example -  https://habr.com/ru/company/ruvds/blog/422089/





When does this error occur?

Let's take a simple example - a function that recursively calls itself.





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



If we try to call such a function, then we will see the error in the console / terminal, which I mentioned above.





But what if you look at how many times the function was executed before the error occurred?





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