为何在函数体内重新分配函数名会改变其行为?
P粉270891688
P粉270891688 2024-01-16 22:35:06
0
1
445

我在逆向工程一些JavaScript时遇到了这个函数:

function fun1() {
    const arr = ["a", "b", "c", "d", "e"];
    fun1 = function () {
        return arr;
    };
    return fun1();
}

对我来说,它看起来是多余的。这段代码似乎:

  1. 声明了一个数组arr
  2. 在函数内部重新定义函数,使其返回arr
  3. 使用return fun1()返回函数本身的结果,现在已经重新定义为返回arr,所以这似乎返回arr

因此,我重写了这个函数,消除了所有多余的代码:

function fun2() {
    const arr = ["a", "b", "c", "d", "e"];
    return arr;
}

然而,我惊讶地发现这两个函数的行为完全不同

fun1()似乎返回对arr的引用,而fun2()似乎返回arr的副本。

这里有一个可运行的最小可复现示例来说明差异:

// 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?

看起来像是发生了魔法...

fun1()fun2()之间有什么区别?

P粉270891688
P粉270891688

全部回复(1)
P粉037880905

当第一次调用时,您的 fun1() 函数重新定义了(相对)全局的 fun1 符号。它将原始函数更改为局部内部函数,该函数关闭了数组。因此,只涉及一个数组,即第一次调用 fun1() 时创建的数组。

另一方面,您的 fun2() 每次调用时都会创建一个全新的数组。

如果您将 fun1() 更改为将内部函数分配给一个局部声明的 fun1 变量,它将与 fun2() 的行为相同。

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板