JavaScript 函数表达式与箭头函数
到目前为止,写函数用的都是 function 关键字加函数名的方式,叫函数声明。JavaScript 里函数还有别的写法。这篇介绍函数表达式和箭头函数。箭头函数是 ES6 新增的写法,语法简洁,现代代码里非常常见。
函数表达式
把匿名函数赋值给变量,就叫函数表达式。匿名函数就是没有名字的函数。
const greet = function () {
console.log('你好');
};
greet(); // 调用方式和函数声明一样
function 关键字后没有函数名,整个匿名函数作为值赋给 const 变量,之后用变量名调用。函数表达式和函数声明的调用方式完全一样,都是 名字()。
箭头函数
箭头函数是 ES6 的写法,去掉 function 关键字,在参数括号和花括号之间加一个箭头 =>。
// 函数表达式写法
const greet1 = function () {
console.log('你好');
};
// 箭头函数写法
const greet2 = () => {
console.log('你好');
};
两种写法功能等价,箭头函数更简洁。真正体现箭头函数威力的是它的简化规则。
箭头函数的简化规则
规则一,只有一个参数时,参数括号可以省略。
const double = n => {
return n * 2;
};
规则二,函数体只有一条返回语句时,可以省略花括号和 return,直接写返回值,表达式的结果就是函数的结果。
const double = n => n * 2;
console.log(double(4)); // 输出 8
两条规则配合使用,短函数一行写完。再看几个对照,感受简化过程
// 普通写法
const add = function (a, b) {
return a + b;
};
// 箭头函数,两个参数,括号不能省
const add2 = (a, b) => a + b;
// 没有参数,空括号
const getTime = () => Date.now();
// 返回对象要加一层圆括号,防止被当成函数体的花括号
const getPerson = () => ({ name: '小明' });
注意返回对象时要给对象加一层圆括号,否则花括号会被当成函数体。这条规则先记住,写多了自然熟练。
三种写法的区别
函数声明、函数表达式、箭头函数在语法层面有一个重要区别,就是提升。函数声明有提升,定义之前就可以调用。函数表达式和箭头函数是赋值给变量的,没有提升,必须先赋值再使用,否则报错。
// 函数声明,定义前调用没问题
sayHi();
function sayHi() {
console.log('你好');
}
// 函数表达式,先调用会报错
sayHello(); // 报错,sayHello 未定义
const sayHello = function () {
console.log('你好');
};
// 箭头函数同样,先调用会报错
sayBye(); // 报错
const sayBye = () => {
console.log('你好');
};
原因在上一篇提过。函数表达式和箭头函数本质是 const 变量,const 有暂时性死区,声明前访问就报错。所以统一先定义后调用最稳妥。
除此之外,箭头函数和普通函数还有一个重要区别,this 的指向不同。this 的知识点在后面专门有一篇讲,到时候会对比说明。这篇只需要记住两者语法不同,this 行为也不同。
小结
- 函数表达式把匿名函数赋值给变量,调用方式和函数声明一样。
- 箭头函数用 => 定义,只有一个参数时可省略括号,函数体只有一条返回语句时可省略花括号和 return。
- 函数声明有提升,函数表达式和箭头函数没有提升,必须先赋值再使用。
- 箭头函数和普通函数在 this 指向上有重要区别,后面专门有一篇对比讲。