When I was reverse engineering some JavaScript code, I came across this function:
function fun1() { const arr = ["a", "b", "c", "d", "e"]; fun1 = function () { return arr; }; return fun1(); }
To me it looks redundant. The code seems to be:
arr
. arr
. return fun1()
returns the result of the function itself, which is now redefined to return arr
, so it appears to return arr
. So I rewrote the function to eliminate 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 is 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()
?
P粉1017086232024-01-11 12:15:16
When first called, your fun1()
function redefines the (relatively) global fun1
symbol. It changes the original function into a local inner function that encloses the array. Therefore, only one array is involved, the one created the first time fun1()
is called.
On the other hand, your fun2()
creates a brand new array on every call.
If you change fun1()
so that the inner function is assigned to a locally declared fun1
variable, it will be the same as fun2( )
works the same way.