协慌网

登录 贡献 社区

什么是词汇范围?

什么是词汇作用域简介?

答案

我通过示例了解它们。 :)

首先,采用类似 C 的语法的词汇作用域(也称为静态作用域):

void fun()
{
    int x = 5;

    void fun2()
    {
        printf("%d", x);
    }
}

每个内部级别都可以访问其外部级别。

Lisp的第一个实现使用另一种称为动态范围的方式,再次使用类似于 C 的语法:

void fun()
{
    printf("%d", x);
}

void dummy1()
{
    int x = 5;

    fun();
}

void dummy2()
{
    int x = 10;

    fun();
}

这里fun既可以访问xdummy1dummy2 ,或x任何函数调用funx在其声明。

dummy1();

将打印 5

dummy2();

将打印 10。

第一个称为静态,因为它可以在编译时推导,第二个称为动态,因为外部作用域是动态的,并且取决于函数的链调用。

我发现静态范围界定对眼睛来说更容易。最终,大多数语言都采用了这种方式,甚至 Lisp 也是如此(对吗?)。动态作用域就像将所有变量的引用传递给调用的函数一样。

作为为什么编译器无法推断函数外部动态范围的示例,请考虑我们的最后一个示例。如果我们这样写:

if(/* some condition */)
    dummy1();
else
    dummy2();

调用链取决于运行时条件。如果为 true,则调用链如下所示:

dummy1 --> fun()

如果条件为假:

dummy2 --> fun()

在这两种情况下fun的外部范围是调用者加上调用者的调用者,依此类推

只需提一下,C 语言既不允许嵌套函数,也不允许动态作用域。

让我们尝试最短的定义:

词法作用域定义了如何在嵌套函数中解析变量名:内部函数包含父函数的范围,即使父函数已经返回

这就是全部!

var scope = "I am global";
function whatismyscope(){
   var scope = "I am just a local";
   function func() {return scope;}
   return func;
}

whatismyscope()()

上面的代码将返回 “我只是本地人”。它不会返回 “我是全球”。因为函数 func()会在函数 whatismyscope 的范围内计算最初定义的位置。

它不会被调用的内容所困扰(即使是全局作用域 / 甚至在另一个函数中),这就是为什么不会打印我为全局范围的全局作用域值的原因。

这称为词法作用域,其中 “根据 JavaScript 定义指南,使用定义时有效的作用域链执行函数”。

词法作用域是一个非常非常强大的概念。

希望这可以帮助..:)