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的a
会在调用bar()时动态查找。由于此时 foo 的 a 已被删除,查找将找到全局 a,而 bar 将打印 5。
Does Javascript Use Dynamic Name Resolution?
是的。考虑以下 example:
eval("var foo = 'foo';");
console.log(foo);
// > "foo"
变量 foo
直到运行时才绑定到词法环境(由于 eval()
语句),但没有抛出错误(并且代码有效)的事实表明名称是动态解析的。
But Javascript uses variable hoisting, which moves var a to the top foo and invalidates my test.
注意:也许您只是说提升妨碍了您尝试执行的测试?如果是这样,请忽略此答案的其余部分...
这种行为实际上是由 提升解释的,而不是因此而无效的。即,
正如您所指出的,由于提升,变量 a
被 创建了 (但没有 分配给 , yet) 在 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()
}
我碰巧对 declarations 和 assignments/initialization[=62] 之间的区别提供了相当详尽的解释=] 在昨晚的回答中。它也解释了此处看到的大部分行为:
这是我要测试的语言是否具有动态名称解析。
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的a
会在调用bar()时动态查找。由于此时 foo 的 a 已被删除,查找将找到全局 a,而 bar 将打印 5。
Does Javascript Use Dynamic Name Resolution?
是的。考虑以下 example:
eval("var foo = 'foo';");
console.log(foo);
// > "foo"
变量 foo
直到运行时才绑定到词法环境(由于 eval()
语句),但没有抛出错误(并且代码有效)的事实表明名称是动态解析的。
But Javascript uses variable hoisting, which moves var a to the top foo and invalidates my test.
注意:也许您只是说提升妨碍了您尝试执行的测试?如果是这样,请忽略此答案的其余部分...
这种行为实际上是由 提升解释的,而不是因此而无效的。即,
正如您所指出的,由于提升,变量
a
被 创建了 (但没有 分配给 , yet) 在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()
}
我碰巧对 declarations 和 assignments/initialization[=62] 之间的区别提供了相当详尽的解释=] 在昨晚的回答中。它也解释了此处看到的大部分行为: