这一次一定要搞懂箭头函数和普通函数的区别

188 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第6天,点击查看活动详情

前言

函数对于我们来说一定是不陌生的,但是平时只是用,但不知道所以然,于是趁着这次一定要搞定箭头函数

深入理解箭头函数

刚开始用箭头函数仅仅是因为写法简洁,尤其是在回调函数里面,不用箭头函数的话就得用function,包括还得在外面用变量去保存this,搞得保存this的变量很多,代码的可读性降低了很多。

ES6的箭头函数横空出世,解决了上述的问题,但是它还有很多的特性还是一知半解。

语法

MDN:箭头函数表达式的语法比函数表达式更简洁,并且没有自己的thisargumentssupernew.target。箭头函数表达式更适用于那些本来需要匿名函数的地方,并且它不能用作构造函数 .

那么我们就利用MDN的解释去理解一下,一个个的实操。

箭头函数没有this

箭头函数是没有this,如果需要访问到会从上一层获取(通过作用域链):

看个箭头函数的例子:

const obj = {
     title:"这是",
     student:["张三","李四"],
     listStudent(){
        console.log("传入listStudent函数的this是不是obj",this === obj)
        this.student.forEach((it)=>{
             console.log("传入循环的回调函数的this是不是obj",this === obj)
             console.log(this.title+"-"+it)
        })
     }
}
obj.listStudent()

这里会打印什么?

分析一下,obj.listStudent这步传入到listStudentthisobj,所以this.student就相当于是obj.student,对此做了一个循环,里面是一个回调函数,那传入的this又是什么呢?刚才我们说道箭头函数是没有this的,会从上一层获取,现在这里的上一层就是obj.student,所以传入的this也是obj

验证一下:

1659601035254.png

如果这里我们用普通函数呢?

const obj = {
     title:"这是",
     student:["张三","李四"],
     listStudent(){
        console.log("传入listStudent函数的this是不是obj",this === obj)
        this.student.forEach(function(it){
             console.log("传入循环的回调函数的this是不是obj",this === obj)
             console.log("传入循环的回调函数的this是不是window",this === window)

          //    console.log(this.title+"-"+it)
        })
     }
}
obj.listStudent()

直接看结果吧

1659601431316.png

可以看见传入回到函数的thiswindow(this默认是window)

解决办法呢?除了箭头函数就是给回调函数使用bind函数绑定this

箭头函数没有 “arguments”

arguments是一个类数组,它是包含了函数调用的参数数组,我们接下来对arguments迭代时需要用Array.from转换一下

我们用一个小例子看一下(普通函数)

function add(){
     console.log(arguments)
     return  Array.from(arguments).reduce((pre,cur)=>pre+cur,0) 
}
console.log(add(1,2,3))

可以看见在函数add()是没有形参的,传入的参数由arguments接收,然后对这个变量进行转化为数组,在进行累加,结果应该都知道是6

1659602172619.png

如果我们使用箭头函数呢?

const  add=()=>{
     console.log(arguments)
     return  Array.from(arguments).reduce((pre,cur)=>pre+cur,0) 
}
console.log(add(1,2,3))

这直接没法玩了,报错了,不知道arguments是个什么东西,使用剩余参数(...)就行

1659602258833.png

得出结论:箭头函数没有arguments这玩意

箭头函数不能new

通俗来说就是箭头函数不能用作构造函数,我们都知道普通函数是可以用作构造函数的。

其实我们这个在第一个就证明了,箭头函数没有this,自然就不能作为构造函数

但是我们还是具体看一看

用普通函数看看:

function Add(a){
      this.a = a;
}
const add = new Add(4);
console.log(add.a)

毋庸置疑打印的结果是4.说明new出来的实例能够使用

1659602980648.png

我们再用箭头函数看看:

const  Add=(a)=>{
      this.a = a;
}
const add = new Add(4);
console.log(add.a)

这有没法玩了,浏览器报了错,没有constructor

1659603092499.png

得出结论:箭头函数不能new

箭头函数不能super

super一般是在类中使用,所有我们用类来看看:

用箭头函数看看能不能用super

class Parent{
   show(name){
      console.log("父元素"+name)
   }
}
class children extends Parent{
   show(name){
      const outer = ()=>{
           super.show(name)
      }
      outer()
   }
   conName(name){
      console.log("子元素"+name)
   }
}
new children().show("张三") //父元素张三

结果调用的是父类的show方法 得出结论:箭头函数没有super

end

这次只是搞懂了MDN上的解释,其实其它的箭头函数不能做什么基本都是基于没有this没有prototype等衍生而来的,古德拜。