写作不易,Star是最大鼓励,感觉写的不错的可以给个Star⭐,请多多指教。本博客的Github地址。
[TOC] 箭头函数,就是函数的简写。如果只有一个参数,()可以省,如果只有一个return,{}可以省。 箭头函数作用:定义匿名函数(多数情况下用来定义回调函数)。
特点:
- 语法简洁;
- 没有自己的this,箭头函数定义时所处的作用域的this指向就是其this指向;
- 箭头函数外层有函数,则当前箭头函数的this同外层函数的this指向相同,否则箭头函数的this指向window。
语法:
- 没有参数: () => console.log('xxxx')
- 一个参数: a => a + 2
- 大于一个参数: (a, b) => a + b
- 函数体不用大括号,默认返回结果
- 函数体如果有多条语句,需要用{}包围,若有需要返回的内容,需要手动返回(即return 'xxx'😉。
// 普通函数
function name() {}
// 箭头函数,去掉function,加上=>
// 箭头函数是匿名函数
() => {}
1
2
3
4
5
6
2
3
4
5
6
let show1 = function () {
console.log('abc')
}
let show2 = () => {
console.log('abc')
}
show1(); // 调用函数
show2();
let show4 = function (a) {
return a * 2
}
let show5 = a => a * 2 // 简洁,类似python lambda 函数
console.log(show4(10));
console.log(show5(10));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
箭头函数this指向
const person = {
name: 'lisi',
hobbies: ['Coding', 'Sleeping', 'Reading'],
sayHobbies() {
// console.log(this); // person
// 而forEach中的回调函数既没有通过对象调用,也没有通过call/apply来特意指定this指向,那么this默认是指向window的,严格模式下指向是undefined。
this.hobbies.forEach(function(hobby) {
// console.log(this); // Window
console.log(`${this.name} loves ${hobby}`);
});
}
}
// ES5中函数的this指向调用函数时的对象
// 这里sayHobbies函数是person对象调用的,因此sayHobbies函数中的this指向person
person.sayHobbies();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2
3
4
5
6
7
8
9
10
11
12
13
14
15
在ES6之前,我们一般通过保存this指向的方式来解决回调函数中this指向问题。
const person = {
name: 'lisi',
hobbies: ['Coding', 'Sleeping', 'Reading'],
sayHobbies() {
// console.log(this); // person
const self = this;
this.hobbies.forEach(function(hobby) {
// console.log(this); // Window
console.log(`${self.name} loves ${hobby}`);
});
}
}
person.sayHobbies();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
2
3
4
5
6
7
8
9
10
11
12
13
14
在ES6中,可以通过箭头函数来解决这个问题。
const person = {
name: 'lisi',
hobbies: ['Coding', 'Sleeping', 'Reading'],
sayHobbies() {
// console.log(this); // person
this.hobbies.forEach(hobby => {
// 改用箭头函数,箭头函数中没有this,其this指向是继承自其父作用域的this。
// console.log(this); // person
console.log(`${this.name} loves ${hobby}`);
});
}
}
person.sayHobbies();
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
// 箭头函数 this
var name = 'windowName';
const obj = {
name: 'lisi',
say() {
setTimeout(function() {
console.log(this); // setTimeout中this默认指向window
console.log('name:', this.name);
}, 100);
},
sayWithThis() { // sayWithThis这里this指向obj
let that = this; // setTimeout回调取的是sayWithThis里的this指向
setTimeout(function() {
console.log('this id:', that.name);
}, 1000);
},
sayWithArrow() { // sayWithArrow这里this指向obj
setTimeout(() => { // setTimeout箭头函数回调的this取最近一层非箭头函数的this指向
console.log('array:', this.name);
}, 1500);
},
sayWithGlobalArrow: () => { // 第一层箭头函数的this指向window
setTimeout(() => {
console.log('global array:', this.name);
}, 2000);
}
};
obj.say(); // name: windowName
obj.sayWithThis(); // this id: lisi
obj.sayWithArrow(); // array: lisi
obj.sayWithGlobalArrow(); // global array: windowName
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
需要注意:箭头函数中的this指向是在函数定义时就确定好的,跟普通函数中this指向需要在函数调用的时候才能确定不一样。 箭头函数应用场景:希望函数绑定其父级作用域的this指向,并且不希望箭头函数在调用时其this指向发生改变。
函数形参默认值
function add(a, b) {
a = a || 5;
b = b || 6;
return a + b;
}
console.log(add()); // 11
console.log(add(1, 2)); // 3
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
采用默认参数写法:
function add(a = 5, b = 6) {
return a + b;
}
console.log(add()); // 11
console.log(add(1, 2)); // 3
1
2
3
4
5
6
2
3
4
5
6
第二个参数使用默认值:
function add(a = 5, b = 6) {
return a + b;
}
console.log(add(1)); // 7
1
2
3
4
5
2
3
4
5
第一个参数使用默认值:
function add(a = 5, b = 6) {
return a + b;
}
console.log(add(undefined, 3)); // 8
1
2
3
4
5
2
3
4
5
这里需要显示指定第一个实参为undefined
,才能使第一个参数默认值生效。因此,可以得出ES6中默认参数的实现原理也是运用了typeof a === undefined
来判断是否采用默认参数的。
箭头函数不适用场景
- 作为构造函数或者一个方法需要绑定到对象。
const Person = (name, age) => {
this.name = name;
this.age = age;
}
const person = new Person('lisi', 12); // Uncaught TypeError: Person is not a constructor
1
2
3
4
5
6
2
3
4
5
6
const Person = function(name, age) {
this.name = name;
this.age = age;
}
const person = new Person('lisi', 12);
// console.log(person); // Person { name: 'lisi', age: 12 }
Person.prototype.sayName = () => {
// 这里之所以是undefined的原因:箭头函数的this指向是其父作用域的this,在这里是window。
console.log(this.name); // undefined
};
person.sayName();
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
const Person = function(name, age) {
this.name = name;
this.age = age;
}
const person = new Person('lisi', 12);
Person.prototype.sayName = function() {
console.log(this.name); // lisi
};
person.sayName();
1
2
3
4
5
6
7
8
9
10
11
2
3
4
5
6
7
8
9
10
11
- 需要使用this的时候
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
.box {
width: 100px;
height: 100px;
background-color: aquamarine;
}
.in {
transform: scale(2);
}
</style>
</head>
<body>
<div class="box"></div>
<script>
const box = document.querySelector('.box');
box.addEventListener('click', function() { // 这里不能使用箭头函数,会导致this指向window而不是当前点击的box
this.classList.add('in');
setTimeout(() => { // 这里需要使用箭头函数,使得this指向其父作用域的this指向即box。不使用箭头函数则指向window。
this.classList.remove('in');
}, 2000);
});
</script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
- 需要使用arguments对象
const sum = () => {
// 箭头函数中没有arguments对象
return [...arguments].reduce((pre, cur) => {
return pre + cur;
}, 0);
}
const res = sum(1, 2, 3); // Uncaught ReferenceError: arguments is not defined
console.log(res);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
const sum = function() { // 改成普通函数
return [...arguments].reduce((pre, cur) => {
return pre + cur;
}, 0);
}
const res = sum(1, 2, 3); // Uncaught ReferenceError: arguments is not defined
console.log(res); // 6
1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
如果你就是想使用箭头函数的话,可以采用rest(...)来接收参数:
const sum = (...args) => {
// console.log(args); // [1, 2, 3]
return args.reduce((pre, cur) => {
return pre + cur;
}, 0);
}
const res = sum(1, 2, 3);
console.log(res);
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
剩余参数
应用场景:
- 函数参数的接收
- 解构赋值
const converCurrency = (rate, ...amounts) => {
return amounts.map(item => item * rate);
}
const res = converCurrency(1.2, 100, 200, 300);
console.log(res); // [ 120, 240, 360 ]
1
2
3
4
5
6
2
3
4
5
6
const person = ['lisi', 23, '🏀', '⚽️'];
const [name, age, ...hobbies] = person;
console.log(name, age, hobbies); // lisi 23 [ '🏀', '⚽️' ]
1
2
3
2
3