这里有一些奇怪的代码......
var x = 5;
function fn() {
x = 10;
return;
function x() {}
}
fn();
alert(x);
这是jsFiddle
到底是function x() {}
叫return
什么?为什么不提醒10?
这里有一些奇怪的代码......
var x = 5;
function fn() {
x = 10;
return;
function x() {}
}
fn();
alert(x);
这是jsFiddle
到底是function x() {}
叫return
什么?为什么不提醒10?
function x() {}
被提升到fn
's 范围的开头,这有效地使x
局部变量在x = 10;
被评估之前。
该功能未设置为10
。
更新:上面的句子是错误的。x
实际上设置为10
。var
不用于声明它,但即使是,下面引用中的最后一句仅指 name 的声明部分,而x
不是它对. 的赋值10
。
来自 MDN(重点是我的):
功能
具有不同作用域行为的三种形式:
- 声明:作为父函数顶层的声明
- 表现得像一个 var 绑定,它被初始化为该函数
- 初始化“提升”到父函数的最顶部,在 vars 之上
变量
- 函数范围
- 提升到其功能的顶部
- 在同一范围内重新声明同名是无操作的
函数 x 浮动到顶部,因此您将函数分配给 10
您在 fn 中声明函数 x;因此,您正在使用 x 的本地范围版本。在什么时候声明函数 x 并不重要。当您将 x 设置为 10 时,您实际上在做的是将 x 的函数设置为 10。
此代码还警告 5:
var x = 5;
function fn() {
x = 10;
return;
var x;
}
fn();
alert(x);
重要的一点是您要声明一个局部变量 x
。在 return 语句之后声明一个变量也无关紧要——它仍然是一个局部变量。
删除声明,你会得到 10,因为x
不再是局部变量。
这是由 JavaScript 中变量提升的工作方式引起的。变量声明被提升,但不是它们的赋值。函数声明也与函数体一起提升(尽管函数表达式不是)。
所以你的代码有效地做到了这一点:
var x = 5;
function fn() {
var x;
x = function () {}
x = 10;
return;
}
fn();
alert(x);
因此x
,函数内的声明仅具有本地范围,并且不影响x
主代码中的贴花。
fn() 中的 X 是一个函数,但全局范围内的 x 是一个 var
删除函数 x() {} 部分,x 将被警告 10
这是因为fn
是一个对象,并且x
是该对象的一个属性。局部范围总是比全局更精确。