「这是我参与11月更文挑战的第19天,活动详情查看:2021最后一次更文挑战」
Javascript 箭头函数和普通函数的区别
ES6中新提出了箭头函数(Arrow function)的概念。本质上箭头函数肯定是函数,但是拥有一些和普通函数不一样的特性。这篇文章主要是来梳理一下箭头函数和普通函数的区别。
来看看MDN上的定义
箭头函数
箭头函数表达式的语法比函数表达式更简洁,并且没有自己的this,arguments,super或new.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数。
对应英文版的定义
Arrow function expressions
An arrow function expression is a compact alternative to a traditional function expression, but is limited and can't be used in all situations.
可以发现英文原文应该是箭头函数表达式,从这里也可以知道,箭头函数是一种函数表达式,而不是函数声明。
一、 区别
1. 更简洁的语法
箭头函数的函数体可以像普通函数一样用{}包含,也可以采用简写的方法。
- 简写体中只能写一个表达式,默认将这个表达式作为返回值。
// 块体
let func = a => { return a + a }
// 简写体
let func = a => a + a
- 当参数只有一个时可以省略(),有多个参数时不可以省略
// 正确
let func = (a) => a + a
// 正确
let func = a => a + a
// 正确
let func = (a, b) => a + b
// 错误
let func = a, b => a + a
- 返回对象字面量时必须用圆括号把对象字面量包起来
var func = () => { foo: 1 };
// Calling func() returns undefined!
var func = () => { foo: function() {} };
// SyntaxError: function statement requires a name
2. 不会绑定Arguments对象
箭头函数中不会绑定Arguments对象,取而代之应该使用rest剩余参数,也就是...运算符。
// 无法获取到正确的参数
let func = () => {
console.log(arguments)
}
func(1,2)
// 正确
let func = (...args) => {
console.log(args)
}
func(1,2)
3. 没有属于自己的this
- 箭头函数不会创建自己的
this,它只会从自己的作用域链的上一层继承this。 - 一经绑定就不能再改变。
- 通过 call 或 apply 调用可以执行但不会生效。
var fruit = 'apple'
let person = {
name: 'Alice',
fruit: 'orange',
getName: function () {
console.log(this.name)
},
getFruit: () => {
console.log(this.fruit)
}
}
person.getName() // Alice
person.getFruit() // apple
4. 没有prototype属性
let func = a => a + a
console.log(func.prototype); // undefined
5. 不能用作构造函数
箭头函数不能用作构造函数,即不能通过new进行实例化。
- 为什么箭头函数不能用作构造函数?
从new关键字的操作分析:
- 创建一个空的简单JavaScript对象(即{})
- 链接该对象的原型到构造函数的prototype
- 将步骤1新创建的对象作为this的上下文
- 如果该函数没有返回对象,则返回this
可以发现,因为箭头函数没有自己的this,没有prototype,所以无论是链接还是绑定都无法正常完成。
6. 不能用作生成器
yield关键字通常不能在箭头函数中使用(除非是嵌套在允许使用的函数内)。因此,箭头函数不能用作函数生成器。
7. 没有属于自己的super
箭头函数中也是没有属于自己的super,具体的原因没有找到,有了解的大佬可以交流交流。
8. 没有new.target 关键字
new.target属性允许你检测函数或构造方法是否是通过new运算符被调用的。在通过new运算符被初始化的函数或构造方法中,new.target返回一个指向构造方法或函数的引用。在普通的函数调用中,new.target的值是undefined。
9. 使用箭头函数作为方法
和上述第三点中提到的,因为箭头函数没有自己的this,在捕获外层作用域的this时,this的指向不会发生改变。箭头函数作为方法,this的指向会比较符合预期。