JavaScript-ES6箭头函数使用细则

我们知道在ES6之前使用函数要使用function:

1
2
3
function fn(形参) {
函数体
}

然而在function中this指向的对象不够清晰明确,以及其表达不够简洁,于是引入的箭头函数:

1
2
3
(形参) => {
函数体
}

由于其重要性,以及在vue中的大量使用,我将着重讨论下箭头函数的使用方法函数参数this指向问题

使用方法以及简写条件

1
2
3
4
5
6
7
const fn = function () {
console.log(123) //function写法
}

const fn = () => {
console.log(123) //箭头写法
}

当传入只有一个形参时,小括号可以省略:

1
2
3
4
const fn = x => {
console.log(x+x)
}
fn(1) //2

当函数体只有一行时可以省略大括号:

1
2
3
4
5
6
7
8
9
const fn = x => console.log(x+x)
fn(2) //4

const f = (x,y) => console.log(x+y)
f(1,2) //3

const form = document.querySelector('form')
form.addEventListener('click', ev => ev.preventDefault()) //形参小括号和函数体大括号都省略
//阻止表单默认提交时事件

箭头函数可以直接返回一个对象:

1
2
3
const fn = (uname) => ({ uname: uname }) // 属性: 值
const fn = (uname) => ({ uname }) //属性和值的名字一样的时候也可以简写
fn('ye') //{uname: 'ye'}

这里不用大括号包着是因为对象的大括号和其冲突了,所以用小括号代替了。

箭头函数没有arguments动态参数

箭头函数里面只有剩余参数…arr,所以只能用剩余参数来传入数组进行计算。

1
2
3
4
5
6
7
8
const getSum = (...arr) => {
let sum=0
for(let i = 0;i < arr.length; i++){
sum +=arr[i]
}
return sum
}
console.log(getSum(2,3)); //5

那么何为动态参数,何为剩余参数呢?

arguments动态参数

1
2
3
4
5
6
7
8
9
function getSum() {
let sum=0
console.log(arguments) //[2,3,4]
for(let i = 0;i < arguments.length; i++){
sum +=arguments[i]
}
console.log(sum)
}
getSum(2,3,4) //9

arguments动态参数只存在于function函数里面,其是个伪数组,在函数里充当傀儡。

函数剩余参数

剩余参数没有的固定名字,这里以arr为例。

1
2
3
4
5
6
7
8
9
function getSum(a,b,...arr) { //这里arr是名字,可以自定义
let sum=0
console.log(arr) //[4,5]
for(let i = 0;i < arr.length; i++){
sum += arr[i]
}
console.log(sum)
}
getSum(2,3,4,5) //9

可以看到剩余参数顾名思义就是取剩下没有对号入座的参数。a=2,b=3,那么剩下的就由arr接收。注意前面的三个点是展开运算符,它可以让这几个数字组合成一个数组。

1
2
3
4
fn = (...arr) => {
console.log(arr);
}
fn(1,2,3) //[1,2,3]

没有展开运算符:

1
2
3
4
fn = (arr) => {
console.log(arr);
}
fn(1,2,3) //1

箭头函数this问题

我们知道this是指向的是环境对象,比如我们输入:

1
2
3
4
5
6
7
const obj = {
number: '1',
hello: function () {
console.log(this)
}
}
obj.hello() //{number: '1', hello: ƒ}

可以看到,我们定义了一个obj对象然后里面放了一个number和一个hello函数,当我们用obj调用hello函数时,this就指向了obj。那么我们就可以初次判断出谁调用的这个函数,this就指向谁。是不是这样呢?我们可以就单纯输入下面这行。

1
console.log(this) //window

我们发现返回的是window,而我们知道window是作用域链的链头。因为我们清楚其实我们每次调用函数都应该要在前面加上window作为调用的对象,但是这样极其的重复与单调故将其省去了。这样也就说明了this确实是指向其调用的对象。

1
2
3
4
5
function fn() {
console.log(this)
}
fn() //window
window.fn() //window

回到这个论题,我们可以发现每一个新函数都要根据它是被如何调用的来定义这个函数的this值,非常让人讨厌。因此在箭头函数中,箭头函数不会创建自己的this,它只会从自己的作用域链的上一层沿用this。

当我们再输入:

1
2
3
4
5
6
7
const obj = {
number: '1',
hello: () => {
console.log(this)
}
}
obj.hello() //Window

hello的上一级时obj,而调用obj的对象是window,所以输出window。

再比如:

1
2
3
4
5
6
7
8
9
10
11
const obj = {
number: '1',
hello: function () {
let i = 10
const count = () => {
console.log(this)
}
count()
}
}
obj.hello() //{number: '1', hello: ƒ}

count函数的上一层是hello,而调用hello的是obj对象,所以输出obj。

然而在实际开发中,事件回调函数使用箭头函数时,this为全局的window。因此DOM事件回调函数为了简便,还是不太推荐使用箭头函数。

1
2
3
btn.addEventListner('click', function () {
console.log(this) //this指向btn
})

JavaScript-ES6箭头函数使用细则
https://bayeeaa.github.io/2024/04/29/ES6箭头函数/
Author
Ye
Posted on
April 29, 2024
Licensed under