首页  >  问答  >  正文

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

欧阳克欧阳克2686 天前1191

全部回复(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
  • 取消回复