啥是函数声明
function hexo () {
// 函数体
}
啥是函数表达式
const hexo = function () {
// 函数体
}
区别
理解函数声明与函数表达式之间的区别,关键是理解提升
JavaScript 引擎在加载数据 时对它们是区别对待的。 JavaScript 引擎在任何代码执行之前, 会进行预编译。此时会发生函数声明提升,还有其他的提升,这里主要说的函数提升。 会先读取函数声明,并在执行上下文中 生成函数定义。而函数表达式必须等到代码执行到它那一行,才会在执行上下文中生成函数定义。
示例
函数声明提升
// 没问题
console.log(sum(10, 10));
function sum(num1, num2) {
return num1 + num2;
}
以上代码可以正常运行,因为函数声明会在任何代码执行之前先被读取并添加到执行上下文。这个 过程叫作函数声明提升(function declaration hoisting)。在执行代码时,JavaScript 引擎会先执行一遍扫描, 把发现的函数声明提升到源代码树的顶部。因此即使函数定义出现在调用它们的代码之后,引擎也会把 函数声明提升到顶部
函数表达式
// 会出错 TypeError: sum is not a function
console.log(sum(10, 10));
var sum = function(num1, num2) {
return num1 + num2;
};
以上代码会报错, 因为函数表达式不会进行函数提升,只有函数声明才会进行函数提升,var sum
会进行变量提升,但是它的初始值会为undefined
的。sum(10,10)
此时sum = undefined
执行的话肯定会报错,当执行到第3条程序时,才会将sum赋值一个函数
如何正确的使用
示例
// 千万别这样做!
if (condition) {
function sayHi() {
console.log('Hi!');
}
} else {
function sayHi() {
console.log('Yo!');
}
}
这段代码看起来很正常,就是如果 condition 为 true,则使用第一个 sayHi()定义;否则,就 使用第二个。事实上,这种写法在 ECAMScript 中不是有效的语法。JavaScript 引擎会尝试将其纠正为适 当的声明。问题在于浏览器纠正这个问题的方式并不一致。多数浏览器会忽略 condition 直接返回第 二个声明。Firefox 会在 condition 为 true 时返回第一个声明。这种写法很危险,不要使用。不过, 如果把上面的函数声明换成函数表达式就没问题了:
// 没问题
let sayHi;
if (condition) {
sayHi = function() {
console.log("Hi!");
};
} else {
sayHi = function() {
console.log("Yo!");
};
}