首頁  >  問答  >  主體

JavaScript的作用域鍊是在函數定義時決定還是在呼叫時?

看到如下的一個閉包問題

var x=10;
function fn() {
    console.log(x);
}

function show(f) {
    var x=20;

    (function() {
        f();
    })();
}
show(fn);

列印的是10而不是20,x在取值時不是沿著作用域鏈向上尋找嗎,如果作用域鍊是在函數建立時確定結果就是10,如果是在呼叫時確定就應該是20 ,有沒有關於作用域鏈準確的說法?這裡準確的作用域鏈應該是什麼樣的呢? fn和show處於同等級還是fn在show內?

欧阳克欧阳克2636 天前1109

全部回覆(5)我來回復

  • 欧阳克

    欧阳克2017-07-05 10:44:15

    作用域鏈是在函數定義的時候確定的.

    在函數內定義的變數不能在函數之外的任何地方訪問,因為變數僅在該函數的域的內部有定義。相對應的,一個函數可以存取定義在其範圍內的任何變數和函數。換言之,定義在全域域中的函數可以存取所有定義在全域域中的變數。在另一個函數中定義的函數也可以存取在其父函數中定義的所有變數和父函數有權存取的任何其他變數。

    https://developer.mozilla.org...

    回覆
    0
  • 習慣沉默

    習慣沉默2017-07-05 10:44:15

    作用域鍊是動態的,所以,在呼叫時確定。
    但是你的這個程式碼中,閉包定義的function()是綁定的最外層的作用域
    function所申明的函數預設是綁定的外層的作用域

    (我也是在學習中。。)

    回覆
    0
  • PHP中文网

    PHP中文网2017-07-05 10:44:15

    在函數創建的時候創建一個包含全域變數物件的作用域鏈,儲存在內部[[Scope]]屬性中。函數執行的時候會創造一個執行環境,透過複製[[Scope]]屬性中的對象,建構執行環境的作用域鏈,並把自己的活動對象推入該作用域鏈的前端以此形成完整的作用域鏈。 [[Scope]]保存的是對全域變數的引用,而不是值的複製。

    var a = 10;
    function f(){
        console.log(a);
    };
    function foo(){
        a = 20;
        f();
    };
    foo() // 20;

    回覆
    0
  • 阿神

    阿神2017-07-05 10:44:15

    閉包的呼叫方式和下面效果等價的,下面舉得例子透過對比說明了,作用域鍊是和函數定義時位置相關的。

    var x=10;
    function fn(){
        console.log(x);
    }
    function show() {
        var x=20;
        fn();
    }
    show();  //输出10
    -----------------------
    var x=10;
    function show() {
        var x=20;
        function fn(){
            console.log(x);
        }
        fn();
    }
    show();  //输出20

    相關問題連結補充。 /q/10...。有關於作用域鏈的討論。

    回覆
    0
  • 扔个三星炸死你

    扔个三星炸死你2017-07-05 10:44:15

    非嚴格模式任何IIFE的this指向都是window

    以上文不對題。 。 。

    回覆
    0
  • 取消回覆