您的示例将在任何遵循 ECMAScript 标准的浏览器中运行(至少在这个问题上都可以)。
请参阅规范的第 10.3-10.5 节。
首先设置本地范围,然后实际运行函数体。
阅读 10.5(该部分真的不是很长)以了解为什么 @meder 的答案是正确的。
如果您不想自己阅读规格:
10.5 告诉以该顺序声明变量(如果某个名称出现两次则覆盖):
从外部范围继承=设置将影响外部范围:
本地范围 = 设置不会影响外部范围:
- 参数(从左到右)。
- 参数对象。
- 声明所有内部变量(如果有的话,不覆盖当前值,
undefined
如果没有的话)
总而言之:
返回函数 x 本身:
function x() {
return x;
}
返回参数 x:
function x(x) {
return x;
}
返回内部函数 x:
function x(x) {
return x; // the return does no harm, x is already set
function x() {} // before the actual body is evaluated
}
还返回内部函数 x:
function x(x) {
var x; // in this case a no-op
return x;
function x() {}
}
返回 42:
function x(x) {
var x = 42; // overwrite x in local scope
return x;
function x() {}
}
返回第二个参数:
function x(x,x) { // assign left to right, last one "wins"
return x; // arguments[0] would still name the first argument
}
第二次调用时返回 2 x
,因为 x 设置为内部函数:
function x() {
x = function() { return 2; } // set x in outer scope
return 1;
}