猜猜看
function a () {
console.log('函数声明')
}
var a = function () {
console.log('函数表达式')
}
a()
这个输出啥?
var a = function () {
console.log('函数表达式')
}
function a () {
console.log('函数声明')
}
a()
这个又输出啥?
var a;
function a () {
console.log('函数声明')
}
a = function () {
console.log('函数表达式')
}
a()
这个呢?
分析
在分析前,先给出结论:
JavaScript 引擎在加载数据时对它们是区别对待的。JavaScript 引擎在任何代码执行之前,会先读取函数声明,并在执行上下文中生成函数定义。而函数表达式必须等到代码执行到它那一行,才会在执行上下文中生成函数定义。 ---摘自《JavaScript高级程序设计(第四版)》10.7 函数声明与函数表达式
红宝书说,函数声明是在最开始就声明并生成函数定义,而函数表达式的函数声明是在执行到那一行时才定义的。这么说来,如果同时有个同名的函数声明和函数表达式,不论二者谁在前,最终都会被函数表达式生成的函数定义而覆盖。
下面来看上面几个例子:
声明和执行顺序是:首先函数a声明并定义了函数,然后又声明了变量a。接着开始执行代码,等到执行到给函数变量a赋值时,又重新定义了函数。所以最终,函数表达式的定义把声明函数的函数定义覆盖了。
这个相对于第一个,变量a的声明写在了最前面,但是,依然是先声明和定义函数声明的函数,顺序不变。
这个把函数表达式的声明和定义都写在了最开始,但是,仍然不影响执行顺序。
我们通过变量类型看:
函数声明后,就算是再声明一个相同名字的变量,也不会影响到函数声明的类型。
但是如果变量声明赋值了,之前的函数定义就会被覆盖,类型就变化了。