I came across this function while reverse engineering some JavaScript:
function fun1() { const arr = ["a", "b", "c", "d", "e"]; fun1 = function () { return arr; }; return fun1(); }
To me it looks redundant. This code seems to be:
arr
. arr
. return fun1()
returns the result of the function itself, which has now been redefined to return arr
, so this appears to return arr
. Therefore, I rewrote this function, eliminating all redundant code:
function fun2() { const arr = ["a", "b", "c", "d", "e"]; return arr; }
However, I was surprised to find that the two functions behaved completely differently.
fun1()
appears to return a reference to arr
, while fun2()
appears to return a copy of arr
.
Here's a minimal reproducible runnable example to illustrate the difference:
// This function is redefined inside itself to return arr function fun1() { const arr = ["a", "b", "c", "d", "e"]; fun1 = function() { return arr; }; return fun1(); } // Why not return arr directly? function fun2() { const arr = ["a", "b", "c", "d", "e"]; return arr; } // But the result is different... let test_fun_1 = fun1(); test_fun_1.pop(); test_fun_1 = fun1(); console.log("Logging test_fun_1"); console.log(test_fun_1); // ["a", "b", "c", "d"] let test_fun_2 = fun2(); test_fun_2.pop(); test_fun_2 = fun2(); console.log("Logging test_fun_2"); console.log(test_fun_2); // ["a", "b", "c", "d", "e"] // What is this magic?
Looks like magic happened...
What is the difference betweenfun1()
and fun2()
?
When first called, your
fun1()
function redefines the (relatively) globalfun1
symbol. It changes the original function into a local inner function which closes the array. Therefore, only one array is involved, the one created the first timefun1()
is called.On the other hand, your
fun2()
will create a brand new array every time it is called.If you change
fun1()
to assign the inner function to a locally declaredfun1
variable, it will be the same asfun2()
behaves the same.