繁体   English   中英

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

[英]Does Javascript Use Dynamic Name Resolution?

这是我测试一种语言是否具有动态名称解析的方法。

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将显示undefined

如果JS动态地解析名称,则在调用bar()时将动态查找bar的a 由于foo's a已经被删除,查找将找到全局a,bar将显示5。

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

是。 考虑以下示例

eval("var foo = 'foo';");

console.log(foo);
// > "foo"

变量foo直到运行时才绑定到词法环境(由于eval()语句),但是没有引发错误(并且代码有效)的事实表明,该名称是动态解析的。


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

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

实际上,此行为是通过吊装来解释 ,而不是通过吊销来消除的。

  • 如您所指出的,由于提升,变量afoo()函数的顶部创建 (但尚未分配给 foo()

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

  • 接下来,您的值赋给10a 请注意,这是您实际调用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()
}

我恰好在昨晚的一个答案中提供了关于声明赋值 / 初始化之间差异的相当详尽的解释。 它也解释了这里看到的许多行为: 声明与初始化变量?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM