与大多数其他答案似乎暗示的相反,这与类型无关,很容易推断(更不用说效率了)。这完全是关于作用域的明确语义。
在允许语言结构的非平凡嵌套的语言中,对变量所属的位置以及哪些标识符引用同一个变量有明确的规则很重要。为此,每个变量都需要一个明确的范围来定义它的可见位置。如果没有显式声明变量(无论有无类型注释),这在一般情况下是不可能的。
考虑一个简单的函数(您可以使用其他形式的嵌套范围构造类似的示例):
function f() {
i = 0
while (i < 10) {
doSomething()
i = i + 1
}
}
function g() {
i = 0
while (i < 20) {
f()
i = i + 1
}
}
怎么了?要告诉您,您需要知道i
将在哪里绑定:在全局范围内还是在本地函数范围内?后者意味着两个函数中的变量是完全独立的,而前者将使它们共享——并且这个特定的示例永远循环(尽管全局范围可能是其他示例中的意图)。
对比上面的
function f() {
var i = 0
while (i < 10) {
doSomething()
i = i + 1
}
}
function g() {
var i = 0
while (i < 20) {
f()
i = i + 1
}
}
对比
var i
function f() {
i = 0
while (i < 10) {
doSomething()
i = i + 1
}
}
function g() {
i = 0
while (i < 20) {
f()
i = i + 1
}
}
这使得不同的可能含义非常清楚。
一般来说,没有好的规则能够(1)猜测程序员的真正意思,(2)在程序扩展或重构下足够稳定。程序越大、越复杂,情况就越糟糕。
避免多义性和令人惊讶的错误的唯一方法是要求变量的显式声明——这是所有合理的语言所做的。(这是语言设计 101,已经有 50 年了,不幸的是,这并不能阻止新一代的语言“设计者”一遍又一遍地重复同样的老错误,尤其是在所谓的脚本语言中。直到他们学会以艰难的方式吸取教训并纠正错误,例如 ES6 中的 JavaScript。)