为什么这个 Javascript 函数在内部重新定义时行为会有所不同?

问题描述 投票:0回答:1

我在对一些 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()
有什么区别?

javascript reverse-engineering
1个回答
3
投票

您的

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

另一方面,您的

fun2()
每次被调用时都会创建一个全新的数组。

如果更改

fun1()
以便将内部函数分配给 本地声明的
fun1
变量,它将与
fun2()
工作相同。

© www.soinside.com 2019 - 2024. All rights reserved.