javascript recursive stack overflow - javascript

Is there anybody would explain why the result is different below?
// test one
function computeMaxCallStackSize() {
try {
return computeMaxCallStackSize() + 1;
} catch (e) {
return 1;
}
}
console.log(computeMaxCallStackSize());
result is 17958
// test two
function computeMaxCallStackSize() {
try {
return 1 + computeMaxCallStackSize();
} catch (e) {
return 1;
}
}
console.log(computeMaxCallStackSize());
result is 15714
When the position of the function 'computeMaxCallStackSize' is different,the result is different too. What's the reason? Thanks very much!
Running environment:
node.js v6.9.1
OS:Win7

Its not the position but the order of execution which leads to this in the first function the statement
return computeMaxCallStackSize() + 1;
calls the increment first and then adds 1
return 1 + computeMaxCallStackSize();
If you try both return statements as same then it leads to same value. In later one as digit is first the js call stack exceeds overflow sooner as compared to first. The callstack value depends on the order of execution as in 2nd you change the order you get a lower value as recursion happens later.
You can also check by adding some console.log() or local variable call stack will decrease gradually with increase in execution statements.
If you try computeMaxCallStackSize() + 1; in both you will get same value.

Related

Merge Two Arrays and Values [duplicate]

If I have the following for loop
for (var i = 0; i < SomeArrayOfObject.length; i++) {
if (SomeArray[i].SomeValue === SomeCondition) {
var SomeVar = SomeArray[i].SomeProperty;
return SomeVar;
}
}
Does the return statement stop the function's execution?
Yes, functions always end whenever their control flow meets a return statement.
The following example demonstrates how return statements end a function’s execution.
function returnMe() {
for (var i = 0; i < 2; i++) {
if (i === 1) return i;
}
}
console.log(returnMe());
Notes: See this other answer about the special case of try–catch–finally and this answer about how the forEach callback has its own function scope, so it will not break out of the containing function.
In most cases (including this one), return will exit immediately. However, if the return is in a try block with an accompanying finally block, the finally always executes and can "override" the return in the try.
function foo() {
try {
for (var i = 0; i < 10; i++) {
if (i % 3 == 0) {
return i; // This executes once
}
}
} finally {
return 42; // But this still executes
}
}
console.log(foo()); // Prints 42
This code will exit the loop after the first iteration in a for of loop:
const objc = [{ name: 1 }, { name: 2 }, { name: 3 }];
for (const iterator of objc) {
if (iterator.name == 2) {
return;
}
console.log(iterator.name);// 1
}
the below code will jump on the condition and continue on a for of loop:
const objc = [{ name: 1 }, { name: 2 }, { name: 3 }];
for (const iterator of objc) {
if (iterator.name == 2) {
continue;
}
console.log(iterator.name); // 1 , 3
}
The return statement stops a loop only if it's inside the function (i.e. it terminates both the loop and the function). Otherwise, you will get this error:
Uncaught SyntaxError: Illegal return statement(…)
To terminate a loop you should use break.
Yes, once the return statement is executed, the entire function is exited at that very point.
Just imagine what would happen if it did not and continued looping, and executing that return statement each time? It would invalidate it's meaning of returning a value when you think about it.
The answer is yes, if you write return statement the controls goes back to to the caller method immediately.
With an exception of finally block, which gets executed after the return statement.
and finally can also override the value you have returned, if you return inside of finally block.
LINK: Try-catch-finally-return clarification
Return Statement definition as per:
Java Docs:
a return statement can be used to branch out of a control flow block
and exit the method
MSDN Documentation:
The return statement terminates the execution of a function and
returns control to the calling function. Execution resumes in the
calling function at the point immediately following the call.
Wikipedia:
A return statement causes execution to leave the current subroutine
and resume at the point in the code immediately after where the
subroutine was called, known as its return address. The return address
is saved, usually on the process's call stack, as part of the
operation of making the subroutine call. Return statements in many
languages allow a function to specify a return value to be passed back
to the code that called the function.
"return" does exit the function but if you want to return large sums of data, you can store it in an array and then return it instead of trying to returning each piece of data 1 by 1 in the loop.

How do I get my For loop to not finish early but still return an array in a function? [duplicate]

If I have the following for loop
for (var i = 0; i < SomeArrayOfObject.length; i++) {
if (SomeArray[i].SomeValue === SomeCondition) {
var SomeVar = SomeArray[i].SomeProperty;
return SomeVar;
}
}
Does the return statement stop the function's execution?
Yes, functions always end whenever their control flow meets a return statement.
The following example demonstrates how return statements end a function’s execution.
function returnMe() {
for (var i = 0; i < 2; i++) {
if (i === 1) return i;
}
}
console.log(returnMe());
Notes: See this other answer about the special case of try–catch–finally and this answer about how the forEach callback has its own function scope, so it will not break out of the containing function.
In most cases (including this one), return will exit immediately. However, if the return is in a try block with an accompanying finally block, the finally always executes and can "override" the return in the try.
function foo() {
try {
for (var i = 0; i < 10; i++) {
if (i % 3 == 0) {
return i; // This executes once
}
}
} finally {
return 42; // But this still executes
}
}
console.log(foo()); // Prints 42
This code will exit the loop after the first iteration in a for of loop:
const objc = [{ name: 1 }, { name: 2 }, { name: 3 }];
for (const iterator of objc) {
if (iterator.name == 2) {
return;
}
console.log(iterator.name);// 1
}
the below code will jump on the condition and continue on a for of loop:
const objc = [{ name: 1 }, { name: 2 }, { name: 3 }];
for (const iterator of objc) {
if (iterator.name == 2) {
continue;
}
console.log(iterator.name); // 1 , 3
}
The return statement stops a loop only if it's inside the function (i.e. it terminates both the loop and the function). Otherwise, you will get this error:
Uncaught SyntaxError: Illegal return statement(…)
To terminate a loop you should use break.
Yes, once the return statement is executed, the entire function is exited at that very point.
Just imagine what would happen if it did not and continued looping, and executing that return statement each time? It would invalidate it's meaning of returning a value when you think about it.
The answer is yes, if you write return statement the controls goes back to to the caller method immediately.
With an exception of finally block, which gets executed after the return statement.
and finally can also override the value you have returned, if you return inside of finally block.
LINK: Try-catch-finally-return clarification
Return Statement definition as per:
Java Docs:
a return statement can be used to branch out of a control flow block
and exit the method
MSDN Documentation:
The return statement terminates the execution of a function and
returns control to the calling function. Execution resumes in the
calling function at the point immediately following the call.
Wikipedia:
A return statement causes execution to leave the current subroutine
and resume at the point in the code immediately after where the
subroutine was called, known as its return address. The return address
is saved, usually on the process's call stack, as part of the
operation of making the subroutine call. Return statements in many
languages allow a function to specify a return value to be passed back
to the code that called the function.
"return" does exit the function but if you want to return large sums of data, you can store it in an array and then return it instead of trying to returning each piece of data 1 by 1 in the loop.

if statements vs shortened if statements [duplicate]

If I have the following for loop
for (var i = 0; i < SomeArrayOfObject.length; i++) {
if (SomeArray[i].SomeValue === SomeCondition) {
var SomeVar = SomeArray[i].SomeProperty;
return SomeVar;
}
}
Does the return statement stop the function's execution?
Yes, functions always end whenever their control flow meets a return statement.
The following example demonstrates how return statements end a function’s execution.
function returnMe() {
for (var i = 0; i < 2; i++) {
if (i === 1) return i;
}
}
console.log(returnMe());
Notes: See this other answer about the special case of try–catch–finally and this answer about how the forEach callback has its own function scope, so it will not break out of the containing function.
In most cases (including this one), return will exit immediately. However, if the return is in a try block with an accompanying finally block, the finally always executes and can "override" the return in the try.
function foo() {
try {
for (var i = 0; i < 10; i++) {
if (i % 3 == 0) {
return i; // This executes once
}
}
} finally {
return 42; // But this still executes
}
}
console.log(foo()); // Prints 42
This code will exit the loop after the first iteration in a for of loop:
const objc = [{ name: 1 }, { name: 2 }, { name: 3 }];
for (const iterator of objc) {
if (iterator.name == 2) {
return;
}
console.log(iterator.name);// 1
}
the below code will jump on the condition and continue on a for of loop:
const objc = [{ name: 1 }, { name: 2 }, { name: 3 }];
for (const iterator of objc) {
if (iterator.name == 2) {
continue;
}
console.log(iterator.name); // 1 , 3
}
The return statement stops a loop only if it's inside the function (i.e. it terminates both the loop and the function). Otherwise, you will get this error:
Uncaught SyntaxError: Illegal return statement(…)
To terminate a loop you should use break.
Yes, once the return statement is executed, the entire function is exited at that very point.
Just imagine what would happen if it did not and continued looping, and executing that return statement each time? It would invalidate it's meaning of returning a value when you think about it.
The answer is yes, if you write return statement the controls goes back to to the caller method immediately.
With an exception of finally block, which gets executed after the return statement.
and finally can also override the value you have returned, if you return inside of finally block.
LINK: Try-catch-finally-return clarification
Return Statement definition as per:
Java Docs:
a return statement can be used to branch out of a control flow block
and exit the method
MSDN Documentation:
The return statement terminates the execution of a function and
returns control to the calling function. Execution resumes in the
calling function at the point immediately following the call.
Wikipedia:
A return statement causes execution to leave the current subroutine
and resume at the point in the code immediately after where the
subroutine was called, known as its return address. The return address
is saved, usually on the process's call stack, as part of the
operation of making the subroutine call. Return statements in many
languages allow a function to specify a return value to be passed back
to the code that called the function.
"return" does exit the function but if you want to return large sums of data, you can store it in an array and then return it instead of trying to returning each piece of data 1 by 1 in the loop.

Maximum call stack size exceeded in recursive function

I have a recursive function which bubblesorts through an array in Javascript. The function calls on itself, which results in it exceeding the stack size of the browser and returning the error:
RangeError: Maximum call stack size exceeded
I understand the problem, and I've tried to wrapping the line which calls itself with setTimeout. This works, but, even if I set the time to 1ms, the sorting is significantly slower than if the setTimeout didn't exist.
Here's the function:
var pieces = [........]; // jumbled array
bubbleSort(0);
function bubbleSort(a) {
if (a < bars-1) {
onBar = a;
} else {
onBar = 0;
}
if (pieces[onBar] < pieces[onBar + 1]) {
// Correct order
bubbleSort(onBar + 1);
} else {
// Incorrect order
var p1 = pieces[onBar];
var p2 = pieces[onBar + 1];
pieces[onBar] = p2;
pieces[onBar + 1] = p1;
bubbleSort(onBar + 1);
}
}
For some strange reason, if I wrap one of the call lines in a setTimeout and leave the other untouched the function runs without any errors, but as soon as I leave both unwrapped it returns an error.
Thanks for your time. Any help appreciated.
You need a branch where you return without ever calling bubbleSort.

google script (JS) - maximum recursion depth

What is the maximum recursion depth in Google Apps Script scripts? I have a function, match_recurse, which looks like the following pseudocode:
function match_recurse(array) {
for (i=0, i<3, i++) {
var arr2 = array.copy().push(i);
if (is_done(arr2)) break;
match_recurse(arr2);
}
}
(It also returns its results, but I don't want to bloat the question.)
Now, because the execution errored, the execution transcript and the logs were not saved, so I have no way of knowing whether my is_done function is doing its job wrong. I can do a few cases of the problem on paper and check recursion depth, but I don't know what the maximum is supposed to be.
Looking on the web, I saw an article mentioning that IE has a max call stack of 13 if you go through the Window object, but nothing else.
It is 1000, as one can see from here:
function recurse(i) {
var i = i || 1;
try {
recurse(i+1);
} catch (e) {
Logger.log(i);
}
}
The stack depth value is not documented. Executing the following code shows that this value is equal to 1000.
function getStackDepth(curvalue) {
try {
curvalue = getStackDepth(curvalue) + 1;
}
catch(err) {
}
return curvalue;
}
function test() {
var depth = getStackDepth(2);
debugger;
}

Categories