【js基础】函数声明和函数表达式

376 阅读2分钟

猜猜看

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的声明写在了最前面,但是,依然是先声明和定义函数声明的函数,顺序不变。

这个把函数表达式的声明和定义都写在了最开始,但是,仍然不影响执行顺序。

我们通过变量类型看:

函数声明后,就算是再声明一个相同名字的变量,也不会影响到函数声明的类型。

但是如果变量声明赋值了,之前的函数定义就会被覆盖,类型就变化了。