编程语言
首页 > 编程语言> > Javascript-如果在定义函数时创建了函数的词法环境,那么为什么在函数之后可以声明一个自由变量?

Javascript-如果在定义函数时创建了函数的词法环境,那么为什么在函数之后可以声明一个自由变量?

作者:互联网

编辑:感谢您的答案,我想我现在明白了.它需要了解范围和吊装.以下是一个我认为很好地说明了这两个示例的新示例:

var a = function (){
    alert(x);
}
var x = 1;

(function(){
    var x = 2;
    a();
})();

上面的警报1.警报作用范围由该警报1而不是2来说明,而起吊作用则由以下事实说明:“ var x = 1”行位于a的声明和带有$的匿名函数的定义之后“警报(x)”.据称,吊装意味着以上等同于以下(来源:http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html):

var x;
var a = function (){
    alert(x);
}
x = 1;

(function(){
    var x = 2;
    a();
})();

因此,由于x是在函数定义之前有效地初始化的,因此“ alert(x)”中的x与随后设置为1的x是相同的.

由于JS使用词法作用域,因此“ var x = 2”行不会覆盖与a关联的x.

那是对的吗?

-原始问题-

我花了整整一天的时间试图弄清楚这一点.我已经阅读了一些有关Java语言中的作用域和闭包的文章,但这仍然使我难以理解.

有人告诉我,函数的词法环境是在定义函数时创建的,而不是在执行时创建的.

因此,如果在程序的任何地方都没有声明名为x的变量,那么当我这样做时指向的匿名函数的关闭环境是什么?

var a = func(){
    var y = 7; //just for illustrative purposes
    alert(x);
});

我的理解是环境是变量名到值的映射…所以

y: 7
x: ?

那是对的吗?以下代码警告“ 10”:

(function (){
    var a = function(){
        alert(x);
    };
    var x = 10;
    a();
})();

我的猜测是,当调用a时,JS检查关闭环境中是否有x的映射,但没有找到映射,随后检查了本地环境,并找到了由“ var x = 10”设置为10的x.那正确吗?

如果是这种情况,那么我希望以下内容也能起作用,但事实并非如此:

var a = function(){
    alert(x);
};

(function (){   
    var x = 10;
    a();
})();

我希望发生的是,当执行a时,出现“ alert(x);”.运行时,它检查x的关闭环境,没有发现,然后检查“ var x = 10”所在的外部环境并找到x.但是相反,我得到一个未定义x的错误.

最初定义a的匿名函数时,如果我能知道解释器完成的“准备”工作可能会有所帮助-当解释器在“ alert(x)”中遇到x时.

谢谢

解决方法:

将闭包视为堆栈.每个函数在该堆栈中都有一个map / hash.这是一个示例,其中每个级别都有一个x的值,该值被子闭合覆盖.

function a(){
  var x = 2;
  function b(){
    var x = 3;
    function c(){
      var x = 4;
    }
  }
}

当引用x的值时,js处理器查找当前的闭包.查找未定义,它将遍历闭包堆栈以尝试查找值.只有达到最高级别或“全局”范围时,它才会放弃并给出“未定义”的值.

您的示例在这里:

var a = function(){
    alert(x); //no value of x in this closure
};

//no value of x in this closure either

(function (){   
    var x = 10; //this is a completely separate stack
    a(); //no value of 'a' in this closure, but there is one in global scope    
})();

我可以在不知道匿名函数中的“ x”的情况下看到对“ a”函数的困惑.关闭范围是按“书面”定义的,而不是“按要求的”定义.您不能从该闭包范围之外插入或混淆函数闭包范围中的变量.这是关于js的事情之一,这让我发疯,我希望与众不同.我真希望有一组关键字可以解决闭包范围…

标签:scope,closures,javascript
来源: https://codeday.me/bug/20191121/2055276.html