Webcourse/05-JavaScript之ES6语法/06-ES6:箭头函数.md
2020-08-23 23:32:42 +08:00

209 lines
5.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 前言
ES6 **函数扩展**方面新增了很多特性例如
- 箭头函数
- 参数默认值
- 参数结构赋值
- 剩余参数
- 扩展运算符
- this 绑定
- 尾调用
今天这篇文章我们讲一下箭头函数
## 箭头函数
### 定义箭头函数的语法
语法
```js
(参数1, 参数2 ...) => { 函数体 }
```
解释
- 如果有且仅有 1 个形参`()`可以省略
- 如果函数体内有且仅有 1 条语句`{}`可以省略但前提是这条语句必须是 return 语句
需要强调的是箭头函数是没有函数名的既然如此那要怎么调用箭头函数呢你可以将箭头函数赋值给一个变量通过变量名调用函数也可以直接使用箭头函数我们来看看下面的例子
### 举例
写法 1定义和调用函数传统写法
```javascript
function fn1(a, b) {
console.log('haha');
return a + b;
}
console.log(fn1(1, 2)); //输出结果3
```
写法 2定义和调用函数ES6 中的写法
```javascript
const fn2 = (a, b) => {
console.log('haha');
return a + b;
};
console.log(fn2(1, 2)); //输出结果3
```
上面的两种写法效果是一样的
从上面的箭头函数中我们可以很清晰地看到变量名参数名函数体
另外箭头函数的写法还可以精简一下继续往下看
在箭头函数中如果方法体内只有一句话且这句话是 return 语句那就可以把 `{}`省略写法如下
```javascript
const fn2 = (a, b) => a + b;
console.log(fn2(1, 2)); //输出结果3
```
在箭头函数中如果形参只有一个参数则可以把`()`省略写法如下
```js
const fn2 = (a) => {
console.log('haha');
return a + 1;
};
console.log(fn2(1)); //输出结果2
```
## 箭头函数的 this 的指向
> 箭头函数只是为了让函数写起来更简洁优雅吗当然不只是这个原因还有一个很大的作用是与 this 的指向有关
ES6 之前的普通函数中this 指向的是函数被调用的对象也就是说谁调用了函数this 就指向谁
ES6 的箭头函数中**箭头函数本身不绑定 this**this 指向的是**箭头函数定义位置的 this**也就是说箭头函数在哪个位置定义的this 就跟这个位置的 this 指向相同
代码举例
```js
const obj = { name: '千古壹号' };
function fn1() {
console.log(this); // 第一个 this
return () => {
console.log(this); // 第二个 this
};
}
const fn2 = fn1.call(obj);
fn2();
```
打印结果
```
obj
obj
```
代码解释一定要好好理解下面这句话
上面的代码中箭头函数是在 fn1()函数里面定义的所以第二个 this 第一个 this 指向的是**同一个位置**又因为在执行 `fn1.call(obj)`之后第一个 this 就指向了 obj所以第二个 this 也是指向 obj
### 面试题箭头函数的 this 指向
代码举例
```js
const name = '许嵩';
const obj = {
name: '千古壹号',
sayHello: () => {
console.log(this.name);
},
};
obj.sayHello();
```
上方代码的打印结果是什么你可能很难想到
正确答案的打印结果是`许嵩`因为 `obj` 这个对象并不产生作用域 `sayHello()` 这个箭头函数实际仍然是定义在 window 当中的所以 这里的 this 指向是 window
## 参数默认值
**传统写法**
```javascript
function fn(param) {
let p = param || 'hello';
console.log(p);
}
```
上方代码中函数体内的写法是如果 param 不存在就用 `hello`字符串做兜底这样写比较啰嗦
**ES6 写法**参数默认值的写法很简洁
```javascript
function fn(param = 'hello') {
console.log(param);
}
```
ES6 中定义方法时我们可以给方法里的参数加一个**默认值**缺省值
- 方法被调用时如果没有给参数赋值那就是用默认值
- 方法被调用时如果给参数赋值了新的值那就用新的值
如下
```javascript
var fn2 = (a, b = 5) => {
console.log('haha');
return a + b;
};
console.log(fn2(1)); //第二个参数使用默认值 5。输出结果6
console.log(fn2(1, 8)); //输出结果9
```
**提醒 1**默认值的后面不能再有**没有默认值的变量**比如`(a,b,c)`这三个参数如果我给 b 设置了默认值那么就一定要给 c 设置默认值
**提醒 2**
我们来看下面这段代码
```javascript
let x = 'smyh';
function fn(x, y = x) {
console.log(x, y);
}
fn('vae');
```
注意第二行代码我们给 y 赋值为`x`这里的`x`是括号里的第一个参数并不是第一行代码里定义的`x`打印结果`vae vae`
如果我把第一个参数改一下改成
```javascript
let x = 'smyh';
function fn(z, y = x) {
console.log(z, y);
}
fn('vae');
```
此时打印结果是`vae smyh`