var a = function(){
alert("2");
}
function a(){
alert("1");
}
a();
如上所述,我以不同的方式宣布了两个功能。当我运行a()
时,我得到了2.为什么?
答案 0 :(得分:8)
当你在JavaScript中声明一个函数或变量时,它会被“提升”,这意味着JavaScript解释器假装变量(在你的情况下是a
)被声明在文件的顶部罢工>范围。
当该声明采用function a() ...
形式时,该函数的定义将随声明一起提升。
a = function ()...
之类的作业不会被提升,因此作业会在function a() ...
之后发生并覆盖它。
答案 1 :(得分:2)
由于函数和变量声明被“提升”到封闭范围的顶部,因此您的代码等效于此:
// hoisted function declaration (but written as an
// assignment of a function expression to a variable)
var a = function a(){
alert("1");
}
a = function(){
alert("2");
}
a();
因此,a
的后一个值被调用,显示2
,如您所观察到的那样。
答案 2 :(得分:1)
一个字:悬挂。
这是因为变量和函数声明被提升到块的顶部,并且为变量赋值(您在alert(2)情况下执行的操作)仅在这些之后生效。
因此,在{em>声明作为警报1的函数后,a
被赋予一个值作为警告2的函数。
查看此代码的输出:
// this logs the "second" version, even though it might look like `a` was not even declared yet.
console.log('a curently:',a.toString());
var a = function(){
console.log('first');
alert("2");
}
function a(){
console.log('second');
alert("1");
}
a(); //calling a here logs "first" and alerts 2, as you describe.
答案 3 :(得分:0)
@RichieHindle对于正在发生的事情的概念是正确的。变量声明(不是它们的赋值)和使用function关键字声明的函数都被提升到作用域的顶部;并按照javascript运行时解析它们的顺序。
实际上,浏览器会对您的代码进行解析和解释,如下所示:
var a;
function a(){
alert("1");
}
a = function(){
alert("2");
}
a(); // alerts "2"
此处发挥的另一个影响是遮蔽,这意味着对a
的第二个赋值会覆盖声明为函数的a
的先前赋值。同一范围内的同名变量可以互相覆盖,因为Javascript没有严格的变量类型。在编写Javascript并依赖于提升时要注意的事情。
这也是为什么许多Javascript开发人员和样式指南建议将变量声明在范围的顶部而不依赖于提升的副作用,因为您(或其他人正在处理您的代码)可能最终会出现阴影和重新分配先前在同一范围内声明的变量。