在ES6(ECMAScript 6)之后的JavaScript中引入了箭头函数的概念,这种函数类型看起来略有不同于我们所熟悉的普通函数。在使用箭头函数时,很多开发者都疑惑箭头函数和普通函数有何不同之处。本文将探讨箭头函数与普通函数的区别。
## 1.写法不同
使用箭头函数可以用更为简洁的语句完成函数定义,可以简单的通过一个例子进行说明:
普通函数的写法:
```javascript
function sum(a, b) {
return a + b;
}
```
箭头函数的写法:
```javascript
const sum = (a, b) => a + b;
```
可以发现,箭头函数的定义形式更为简单,不再需要function关键字,而是使用箭头符号“=>”。
## 2.更加简洁
除了写法不同外,箭头函数也是一种更简洁的函数类型。在JavaScript中,如果函数只包含一个表达式,则可以省略大括号以及return关键字。例如:
```javascript
const multiply = (a, b) => a * b;
```
上述例子中,箭头函数只包含一个表达式,因此可以省略大括号和return关键字。
而使用普通函数完成同样的任务,则需要写成这样:
```javascript
function multiply(a, b) {
return a * b;
}
```
可以发现,在这个例子中,箭头函数会更加简洁。
## 3.箭头函数没有自己的this
除了函数写法和函数体简洁度之外,最重要的区别在于箭头函数和普通函数在this的处理上不同。对于普通函数而言,this关键字将指向调用该函数的对象或者上下文,而对于箭头函数而言,则没有自己的this。箭头函数的执行上下文的this与定义时的上下文保持一致,不会被任何调用方式改变。在使用箭头函数时,开发者可以省略.bind()/.call()/.apply()等方法,因为上述方法所实现的就是改变函数体内this指向的功能,而针对箭头函数,不存在这种情况。
```javascript
const user = {
name: 'bob'
};
function sayName() {
console.log(this.name);
}
const sayArrowName = () => {
console.log(this.name);
}
sayName.call(user); // 输出 'bob'
sayArrowName.call(user); // undefined
```
可以看出,在上面的代码中,当我们调用sayName()函数时,this指向了user对象,因此输出了'bob'。而对于sayArrowName箭头函数则输出了undefined,因为箭头函数不存在自己的this,所以也不会从外部上下文里继承this的值。
需要注意的是,如果箭头函数中嵌套了对象字面量,则其内部的this会绑定到该箭头函数的上下文:
```javascript
const user = {
name: 'bob',
sayArrowName: () => {
console.log(this.name);
}
}
user.sayArrowName(); // undefined
```
在上述代码中,由于箭头函数sayArrowName嵌套在user对象字面量中,所以该箭头函数内的this会绑定到该箭头函数的上下文,与外层的user对象没有任何关系,因此输出undefined。
## 4.使用场景不同
由于箭头函数的特性和优雅的书写方式,其在一定情况下更为适合作为函数类型的选择。通常,对于以下几种情况之一,我们推荐使用箭头函数:
1. 简单的功能。当函数中仅包含单一表达式,或者只需要简单地返回某个值时,箭头函数的语法显得更为简洁。
2. 当需要捕获父级作用域的this时。我们知道,由于在JavaScript中函数泛指function、class、object嵌套中的function、method、constructor等,但在父级与子级的语境中,this所引用的对象类型却有所不同。在这种情况下,箭头函数的特性会让你更加方便的访问到父级作用域中this的值。
3. 不需要自己的this时。使用箭头函数可以省略很多代码,因为它们不需要绑定自己的this,所以不需要使用bind()/.call()/.apply()等方法进行绑定操作。
当然,对于更为复杂和功能完善的场景,我们推荐使用普通函数来实现需要的逻辑过程。
## 总结
在JavaScript中,箭头函数和普通函数都是函数类型的一种,但其在书写方式、体积以及使用特性方面都有所不同。在使用上,开发者可以了解到箭头函数与普通函数的不同之处,在选择合适的函数类型时更加得心应手,既能达成任务的目的,又不会占用太多不必要的代码。