简介
箭头函数没有自己的this对象(详见下文)。
不可以当作构造函数,也就是说,不可以对箭头函数使用new命令,否则会抛出错误。
不可以使用arguments对象,该对象在函数体内不存在。如果要用,可以用 rest 参数(...变量名)代替。
不可以使用yield命令,因此箭头函数不能用作 Generator 函数。
其中最难理解且最容易出问题的就是 this 指向的问题,例如:平时我们的UI组件绑定回调方法的时候,会使用bind或者使用箭头函数,后续可能为了方便所有方法都是箭头函数,那样在一些情况下,会出现意想不到的问题(this指向引起的问题)
简而言之:箭头函数的 this 一般绑定锁死为所在函数的 this指向的对象,不会因为调用者而发生改变(对于对象外部没有函数怎么办,其外部可以理解为 main 函数,this 则指向全局对象);而非箭头函数的 this 则取决于调用者,会随着调用者的变化而发生改变
案例
下面使用案例来简单理解一下
class A {
a = 10
printA() {
return this.a
}
printA2 = () => {
return this.a
}
}
class A2 extends A {
a = 29
}
class B {
a = 100
info = new A()
info2 = new A2()
printB() {
console.log(this.info.printA(), this.info.printA2(),
this.info2.printA(), this.info2.printA2())
}
printB2() {
console.log(this.info.printA.call(this), this.info.printA2.call(this),
this.info2.printA.call(this), this.info2.printA2.call(this))
}
}
如果调用 B 里面的 printB 会打印什么,相信很容易出结果,甚至不用过多思考,因为其调用者就是其本身,答案就是
10 10 29 29
如果是调用 B 里面的 printB2 会打印什么(可能小伙伴会问 call 是什么意思,前面有文章讲过,就是用 call 后面传入的对象,调用前面的函数),答案就是下面的
100 10 100 29
首先说1、3的结果,非箭头函数指向调用者,这里调用者都是 class B,那么无论是 class A、class A2中的 printA,其this 都指向了 class B,因此 this.a 则为 class B 的 a 均为 100,所以 1、3 均为 100
然后说2、4的结果,前面讲过,箭头函数没有自己的 this,会被绑定锁死在自己的对象里面,this.info.printA2.call(this),里面的 printA2 的 this 则指向的是 this.info 即 class A,因此里面返回的 this.a 为 class A 的 a=10;
同理,class B 继承了 class A,其也拥有 class A 的 printA2 方法,其 this 指向自然指向的是 class B,因此返回的是 29
然后再来一个案例,测试一下你是否已经理解了
class AAA {
value = 10
value1 = this.value
testObj() {
const obj = {
value: 100,
fun: () => this.value,
fun2: function() {
return this.value
},
fun3: function() {
return this.value1
}
}
console.log(obj.fun(), obj.fun2(), obj.fun3())
}
}
结果:
10 100 undefined
结果跟你想的一样么😯,如果不一样,那跟考试一样,是不是哪些细节没注意到呢😂
arguments知识扩展
为了避免一些同学不了解 arguments, 这里也简介一下正常函数的 arguments,它是函数里面的特殊属性,和调用 this 类似,只不过 arguments 是用来获取参数的,像数组的ArrayLike类型(参数有点像 ArrayLike 类型,但差了个 length,我这里没打印出来哈)
ps:箭头函数就不打印了,其里面的 arguments 不能说没啥用,只能说毫无关系😂
function testFunction(a, b) {
console.log(arguments)
}
testFunction(1, 4)
//[Arguments] { '0': 1, '1': 4 }