Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/475.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript是否使用动态名称解析?_Javascript_Variables_Late Binding - Fatal编程技术网

Javascript是否使用动态名称解析?

Javascript是否使用动态名称解析?,javascript,variables,late-binding,Javascript,Variables,Late Binding,这是我要测试的语言是否具有动态名称解析 function foo() { function bar() { print a } var a = 10 bar() } 如果语言使用动态名称解析,则代码应打印10。否则,它将抛出一个未定义的错误 Javascript打印10。但是Javascript使用变量提升,它将var a移动到顶部foo并使我的测试无效 编辑: 如果我们可以删除JS中的变量,那么以下将是一个极好的测试: var a = 5 fu

这是我要测试的语言是否具有动态名称解析

function foo() {
    function bar() {
        print a
    }
    var a = 10
    bar()
}
如果语言使用动态名称解析,则代码应打印10。否则,它将抛出一个未定义的错误


Javascript打印10。但是Javascript使用变量提升,它将
var a
移动到顶部foo并使我的测试无效

编辑: 如果我们可以删除JS中的变量,那么以下将是一个极好的测试:

var a = 5
function foo() {
    var a = 10
    function bar() {
        print a
    }
    delete a
    bar()
}
foo()
如果JS静态解析名称,则bar的
a
引用foo的
a
。由于foo的
a
被删除(如果可能的话),bar将打印
未定义的

如果JS动态解析名称,则在调用bar()时将动态查找bar的
a
。因为此时foo的a已经被删除,所以查找将找到全局a,而bar将打印5

Javascript是否使用动态名称解析

对。考虑以下事项:

变量
foo
直到运行时才绑定到词法环境(由于
eval()
语句),但是没有抛出错误(代码正常工作)这一事实表明名称是动态解析的



但是Javascript使用变量提升,这会将var a移动到顶部foo并使我的测试无效

注意:也许你只是说吊装妨碍了你要进行的测试?如果是这样,请忽略此答案的其余部分

这种行为实际上是通过提升来解释的,而不是因为提升而失效。即

  • 正如您所指出的,由于提升,变量
    a
    会在
    foo()
    函数的最顶端创建(但尚未分配给)

  • 接下来,您有一个函数声明。碰巧的是,函数声明也被提升到其作用域的顶部

  • 接下来,将值
    10
    分配给
    a
    。请注意,这发生在您实际调用
    bar()
    之前

  • 最后,您实际上调用了
    bar()
    ,此时
    a
    已经被赋值为
    10
    ,从而打印出
    0

将这一切结合在一起,您的
foo()
函数的行为与编写时的行为相同,如下所示:

function foo() {
    // hoisted
    var a;

    // also hoisted
    function bar() {
        // due to hoisting, `a` is lexically in scope here
        console.log(a);
    }

    // the actual assignment
    a = 10

    // the invocation
    bar()
}
就在昨天晚上,我在一个回答中对声明和赋值/初始化之间的区别做了相当透彻的解释。这也解释了这里看到的许多行为:

Javascript是否使用动态名称解析

对。考虑以下事项:

变量
foo
直到运行时才绑定到词法环境(由于
eval()
语句),但是没有抛出错误(代码正常工作)这一事实表明名称是动态解析的



但是Javascript使用变量提升,这会将var a移动到顶部foo并使我的测试无效

注意:也许你只是说吊装妨碍了你要进行的测试?如果是这样,请忽略此答案的其余部分

这种行为实际上是通过提升来解释的,而不是因为提升而失效。即

  • 正如您所指出的,由于提升,变量
    a
    会在
    foo()
    函数的最顶端创建(但尚未分配给)

  • 接下来,您有一个函数声明。碰巧的是,函数声明也被提升到其作用域的顶部

  • 接下来,将值
    10
    分配给
    a
    。请注意,这发生在您实际调用
    bar()
    之前

  • 最后,您实际上调用了
    bar()
    ,此时
    a
    已经被赋值为
    10
    ,从而打印出
    0

将这一切结合在一起,您的
foo()
函数的行为与编写时的行为相同,如下所示:

function foo() {
    // hoisted
    var a;

    // also hoisted
    function bar() {
        // due to hoisting, `a` is lexically in scope here
        console.log(a);
    }

    // the actual assignment
    a = 10

    // the invocation
    bar()
}

就在昨天晚上,我在一个回答中对声明和赋值/初始化之间的区别做了相当透彻的解释。它还解释了这里看到的许多行为:

首先,定义关于变量作用域的“动态名称解析”的含义可能是您所追求的,或者可能有助于您重新表述您的问题,以便更清楚地了解您到底在问什么?但是Javascript使用变量提升,这会将var a移动到最上面的foo并使我的测试无效。“为什么您觉得这会使您的测试无效?@Alnitak通过动态名称解析,我的意思是直到运行时,对变量的引用才附加到实际变量。相反,静态名称解析意味着编译器可以在不运行代码的情况下找出引用指向哪个变量。例如,如果Javascript使用静态名称解析,编译器可能会发现bar()引用的是foo的a,而不是其他的a(比如全局a)。首先,定义变量作用域的“动态名称解析”可能就是您想要的,或者可以帮助您重新表述您的问题,以便更清楚地了解您的问题?”但是Javascript使用变量提升,将var a移到最上面的foo并使我的测试无效。“为什么您认为这会使您的测试无效?@Alnitak By dynamic name resolution,我的意思是,直到运行时,对变量的引用才附加到实际变量。相反,静态名称解析意味着编译器可以在不运行代码的情况下找出引用指向哪个变量。例如,如果Javascript使用静态名称解析,编译器可以判断bar()引用的是foo的a,而不是其他的a(比如全局a)。您似乎在解释测试代码的作用,这不是问题所在。问题是关于名字解析(你甚至承认你不明白它的意思。)@Juhana Fair