[英]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并使我的测试无效。
注意:也许您只是说吊装妨碍了您要执行的测试? 如果是这样,请忽略此答案的其余部分...
实际上,此行为是通过吊装来解释的 ,而不是通过吊销来消除的。 即
如您所指出的,由于提升,变量a
在foo()
函数的顶部创建 (但尚未分配给 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()
}
我恰好在昨晚的一个答案中提供了关于声明与赋值 / 初始化之间差异的相当详尽的解释。 它也解释了这里看到的许多行为: 声明与初始化变量?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.