簡體   English   中英

為什么控制台日志在 IIFE 中起作用?

[英]Why does the console log function a in an IIFE?

 var a = 1; (function a () { a = 2; console.log("a:", a); })();

顯然 a 作為 IIFE(立即調用的函數表達式),函數名稱將覆蓋全局變量 a,這是可以理解的,但是...為什么不在函數本身內將 a 重新分配給數字 2?

 function a() { a = 1; console.log("a:", a); }; function a() { a = 2; console.log("a:", a); }; a();

為什么上面的代碼表現不同?

在命名的 IIFE 中,函數的名稱是一個隱式常量值。

默認情況下重新分配它不會覆蓋它,也不會向您拋出錯誤,但在嚴格模式下,您可以看到它實際上是一個常量,並且會向您拋出一個錯誤:

 var a = 1; (function a () { "use strict"; a = 2; // throws error: Assignment to constant variable console.log("a:", a); })();

我可能是錯的,但我認為下面的代碼

    /* part 1 */
    function a() { 
        a = 1;
        console.log("a1:", a); 
    };
    /* part 2 */
    function a() { 
        a = 2;
        console.log("a1:", a); 
    };
    a();
    console.log("a2:", a);

已經證明它與 Function.name 的 Writable 屬性無關。

https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Function/name

Function.name 只是一個Function 的名稱,與變量本身是否可以重寫無關。

同時,對此結果的另一個流行解釋是,在“命名函數”的范圍內,例如 function a() {...} “與命名函數共享相同名稱的變量”將指向“命名函數”。 ”

這個解釋也是錯誤的。 為什么? 因為上面的代碼輸出的是“a1:2”和“a2:2”。 不僅是“命名函數”中的variable a /* part 2 */ function a() {...}可以改寫,實際上window.a也改寫了,因此a2打印為2。

這意味着,事實上,單獨的命名函數不會使“其范圍內共享相同名稱的變量”指向命名函數本身。 上面的代碼可能如下工作:

    /* part 1 */
    var a = function () { 
        a = 1;
        console.log("a1:", a); 
    };
    /* part 2 */
    var a = function () { 
        a = 2;
        console.log("a1:", a); 
    };
    a();
    console.log("a2:", a);

這意味着我們只能在 IIFE 或指定的命名函數中看到它,例如:

    void function a() { ... }

    var a = function a() { ... }

在命名函數的范圍內,變量與函數本身共享名稱將指向函數本身(而不是全局/窗口)。

事實上,無論語法如何,所需要的是命名函數不附加到全局/窗口。 換句話說,對於與其作用域主同名的變量,其作用域主(一個名稱函數)必須處於“無家可歸”狀態。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM