声明性环境记录和Java范围

时间:2019-11-12 17:33:20

标签: javascript scope

我目前正在学习Javascript范围,并尝试为正在发生的事情制定一些规则。 但是每次意外的行为破坏了它们。所以我需要帮助。

考虑以下示例

console.log("v" in this);    //true
console.log(v)     //undefined
{
    {
        function a() {
            1;
        }
    }
    {
        function a() {
            2;
        }
        {
            function v() {
                3;
            }
        }
    }
}
console.log(a);    //ƒ a() {2}

函数 v 已在内存中,但我无法在第2行使用它。但是在此示例中,我可以使用。

console.log(v);
{
    function v() {
        1;
    }
}

我对编译器在执行脚本之前执行的规则以及评估声明(包括语句)使用 let,const,var function < / strong>声明和 class 声明。 我已经阅读过有关范围的博客,书籍,但几乎所有书籍,变量和函数和类都将它们视为独立的东西,而不是范围D.E.R中附加的属性

1 个答案:

答案 0 :(得分:1)

  

函数v在内存中,但是我不能在第2行使用它。但是在此示例中,我可以

不,两个示例的行为方式相同。在这两种情况下,v都在一个块内声明,并且在两种情况下,其记录位置的值都为undefined

在松散模式(也称为“草率”模式)下,符合特定条件的块中的函数声明会在函数(或全局)作用域而非块中创建提升的绑定(在这种情况下为v)范围。该绑定使用值undefined初始化;直到在逐步执行代码中达到声明时,它才分配给它函数。还有一个 块局部绑定,它遮盖了函数/全局绑定,该绑定在函数的块开始处初始化。是的,这很非常令人困惑;这是因为这是将ES2015中的规则追溯应用到跨浏览器引擎的通用功能子集,这些浏览器引擎已使用块声明的功能(不在规范中,但是允许的扩展)扩展了JavaScript。

但是,请不要依赖它,甚至不要费心将其提交到内存中。这是旧版兼容性的东西。

相反,请使用严格模式,在该模式下,声明成为块的局部声明(完全悬挂在块中),并且不能在其外部完全使用v

"use strict";
console.log("v" in this);    // false
console.log(v)               // ReferenceError
{
    {
        function a() {
            1;
        }
    }
    {
        function a() {
            2;
        }
        {
            function v() {
                3;
            }
        }
    }
}
console.log(a);