六维教程

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 指向上有重要区别,后面专门有一篇对比讲。
上一篇
JavaScript 作用域
下一篇
JavaScript 闭包入门