Javascript 为什么变量声明总是可以覆盖函数声明?

Javascript 为什么变量声明总是可以覆盖函数声明?,javascript,function,variables,declaration,Javascript,Function,Variables,Declaration,无论我是否在变量之后定义函数 var a = 1; function a() {}; typeof a // number function a() {}; var a = 1; typeof a // number 或者如果我在变量之前定义函数 var a = 1; function a() {}; typeof a // number function a() {}; var a = 1; typeof a // number 最后的typeof结果总是number 我在中找到了一些

无论我是否在变量之后定义函数

var a = 1;
function a() {};
typeof a // number
function a() {};
var a = 1;
typeof a // number
或者如果我在变量之前定义函数

var a = 1;
function a() {};
typeof a // number
function a() {};
var a = 1;
typeof a // number
最后的
typeof
结果总是
number

我在中找到了一些关于执行上下文的解释

但这似乎不起作用


那么我该如何解释呢?

这与JavaScript的功能有关。请尝试以下方法:

var a = 1;
var a = function() {};
typeof a // function

通过使用函数语句'function a(){};',多次隐式声明变量,正如其他人所注意到的,由于浏览器注册声明的顺序,它会提升变量并意外地运行

在幕后,该语句实例化一个函数对象,并将结果分配给作为函数名()传递的变量,但这是在执行显式var声明之前完成的,因此会覆盖隐式声明。如果您只需执行以下操作,它将更直观地工作:

var a = 1;
a = function(){};
console.log(typeof a);  // function
从逻辑角度来看,这是一个比另一个答案中的多重var声明更好的选择,因为(即使可以),多次声明变量并不是一个好的做法

具体回答这个问题的“为什么”:这样您就可以使用这些类型的语句来定义函数,并在显式声明中使用它们,如

var a = someFunction();  
function someFunction(){ return 'someVal'; }

如果没有首先解析和提升函数语句,这是不可能的。

如前所述,这与JavaScript提升的工作方式有关。需要注意的主要问题是,JavaScript将把完整的函数定义(连同函数体)提升到顶部,但将变量初始化保持在原来的位置(只提升声明)

所以,如果你写这篇文章:

var a = 1;
function a () {
}
它将被翻译成:

var a;
function a() {
}
a = 1;
function a () {
}
var a;
a = 1;
如果你写这个:

function a () {
}
var a = 1;
它将被翻译成:

var a;
function a() {
}
a = 1;
function a () {
}
var a;
a = 1;
所以无论你做什么,
a=1将保留在最底部

请注意,上述“翻译”应从理论上看。JavaScript可能有办法省略
var a语句。也可能有一个定义的顺序(函数在变量之前被提升,或者反过来)。但是所有这些都不会影响变量初始化的结果,因为变量初始化是唯一一个根本没有被提升的部分。

Try
var a=function(){}
并查看
typeof
返回的内容。函数a(){}将(应该)始终在作用域中的var之前提升。因此,a的最新类型始终是number。这就是为什么在“现代”javascript中最好将命名函数声明为var a=function(){}