无论我是否在变量
之后定义函数var a = 1;
function a() {};
typeof a // number
或者如果我在变量
之前定义函数function a() {};
var a = 1;
typeof a // number
最终typeof
结果始终为number
我在http://davidshariff.com/blog/what-is-the-execution-context-in-javascript/
中找到了关于execution context
的一些解释
Before executing the function code, create the execution context.
......
Scan the context for variable declarations:
If the variable name already exists in the variable object, do nothing and continue scanning.
但这似乎不起作用。
那我怎么解释呢?
答案 0 :(得分:5)
这与JavaScript的variable hoisting有关。试试这个:
var a = 1;
var a = function() {};
typeof a // function
答案 1 :(得分:1)
你通过使用函数语句'function a(){};'隐式地多次声明变量,由于浏览器注册声明的顺序,如其他人所指出的那样提升变量并出现意外行为。
在幕后,此语句实例化一个函数对象,并将结果分配给作为函数名称传递的变量(reference),但这是在执行显式var声明之前完成的,因此会覆盖隐式宣言。如果您只是执行以下操作,它将更直观地工作:
var a = 1;
a = function(){};
console.log(typeof a); // function
从逻辑角度来看,这是一个比其他答案中的多var声明更好的选择,因为(即使你可以),无论如何多次声明变量并不是一个好习惯。
要专门回答这个问题的“原因”:这样你就可以使用这些语句定义函数并在显式声明中使用它们,如
var a = someFunction();
function someFunction(){ return 'someVal'; }
如果未首先解析和提升函数语句,则无法实现。
答案 2 :(得分:0)
如前所述,它与JavaScript提升的工作方式有关。需要注意的主要问题是JavaScript将完整的函数定义(以及函数体)提升到顶部,但保持变量初始化的位置(仅提升声明)。
所以如果你写这个:
var a = 1;
function a () {
}
它将被翻译为:
var a;
function a() {
}
a = 1;
如果你这样写:
function a () {
}
var a = 1;
它将被翻译为:
function a () {
}
var a;
a = 1;
所以无论你做什么,a = 1;
都会保持在最底层。
请注意,理论上应该看到上述“翻译”。如果已经存在具有相同名称的函数声明,则JavaScript可能有一种省略var a;
语句的方法。并且还可能存在已定义的顺序(函数在变量之前或其他方式被提升)。但所有这些都不会影响变量初始化的结果,因为变量初始化是唯一没有提升的部分。