首頁  >  問答  >  主體

內部重新定義的 Javascript 函數的行為差異

當我在逆向工程一些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粉805931281P粉805931281283 天前428

全部回覆(1)我來回復

  • P粉101708623

    P粉1017086232024-01-11 12:15:16

    當第一次呼叫時,您的fun1()函數重新定義了(相對)全域的fun1符號。它將原始函數更改為局部內部函數,該函數封閉了數組。因此,只涉及一個數組,即第一次呼叫fun1()時所建立的數組。

    另一方面,您的fun2()在每次呼叫時都會建立一個全新的陣列。

    如果您更改fun1(),以便將內部函數分配給一個在本地聲明fun1變量,它將與fun2( )的工作方式相同。

    回覆
    0
  • 取消回覆