es6-箭头函数

一 为什么要有箭头函数

我们在日常开发中,可能会需要写类似下面的代码

 const Person = {
    'name': 'little bear',
    'age': 18,
    'sayHello': function () {
      setInterval(function () {
        console.log('我叫' + this.name + '我今年' + this.age + '岁!')
      }, 1000)
    }
  }
  Person.sayHello()

上例的输出结果是什么呢?可能对javascript特性不是很熟悉的同学(我自己也是)会认为输出当然是
我叫little bear,今年18岁咯。如果你的答案是这个的话,那么我要恭喜你,答错了。其实上例的输出结果是我叫undefined,今年我undefined岁。为什么会输出这种结果呢?
这是因为setInterval执行的时候,是在全局作用域下的,所有this指向的是全局window,而window上没有name和age,所以当然输出的是undefined咯。不明白的同学可以去看看this的工作原理this。
那么,我们怎么要解决这个问题呢?
通常的写法是缓存this,然后在setInterval中用缓存的this进行操作,如下

 const Person = {
    'name': 'little bear',
    'age': 18,
    'sayHello': function () {
     let self = this
      setInterval(function () {
        console.log('我叫' + self.name + '我今年' + self.age + '岁!')
      }, 1000)
    }
  }
  const sayHelloFun = Person.sayHello
  sayHelloFun()

使用上叙方法,输出的结果就是大家所期待的我叫little bear,我今年18岁了。
那么,大家可能会觉得这样不科学,明明是写在对象里面的方法,为什么还要使用缓存这个对象才能正确使用。ECMA组织觉得这确实是个问题,之后在es6的新特性里添加了箭头函数,它能很好的解决这个问题。另外箭头函数还用简化代码量的特点。

二 什么是箭头函数

箭头函数的语法非常简单,看一下最简单的箭头函数表示法

() => console.log('Hello')

之前没有接触过箭头函数的人可能会惊讶于其代码的简洁。对比之前如果要写一个这样的函数

function(){
console.log('hello')
}

箭头函数的简洁性一目了然。
更多关于箭头函数语法可点击箭头函数语法

三 和普通函数的区别

从上面的例子中,我们已经可以看出箭头函数的优势。
和普通函数相比,箭头函数主要就是以下两个方面的特点

  • 不绑定this,arguments
  • 更简化的代码语法

第二个特点不需要过多赘述,下面我们来看看不绑定this和arguments这两个特点

3.1 不绑定this
什么叫不绑定this,我个人的理解为箭头函数的this其实就是在定义的时候就确定好的,以后不管怎么调用这个箭头函数,箭头函数的this始终为定义时的this
我们还是以前面的那个setInterval代码为例

const Person = {
    'name': 'little bear',
    'age': 18,
    'sayHello': function () {
      setInterval(function () {
        console.log('我叫' + this.name + '我今年' + this.age + '岁!')
      }, 1000)
    }
Person.sayHello()

当Person.sayHello()去执行setInterval的时候,是在全局作用下执行的所有setInterval回调函数的this就为全局对象。es3-5中的函数this的值和调用这个函数的上下文有关。(注意是调用)
我们用箭头函数重写上诉函数

const Person = {
    'name': 'little bear',
    'age': 18,
    'sayHello': () => {
      setInterval(() => {
        console.log('我叫' + this.name + '我今年' + this.age + '岁!')
      }, 1000)
    }
Person.sayHello()

大家猜猜结果是什么???
输出的是我叫’little bear’,今年18岁嘛?
哈哈,太天真了,我开始也是这样想的,后面输出之后发现结果不对,输出的还是undefined。为什么呢??
因为我把方法写在了对象里,而对象的括号是不能封闭作用域的。所以此时的this还是指向全局对象。
所以,通过以上的错误可以提醒我们,最好不要用箭头函数作为对象的方法。
我们需要重新举一个例子,如下

function Person () {
  this.name = 'little bear',
  this.age = 18
  let self = this
  setInterval(function sayHello () {
    console.log('我叫' + self.name + '我今年' + self.age + '岁!')
  }, 1000)
}
let p = new Person()

缓存this,然后输出,能达到我们想要的结果。
把上述例子改为箭头函数的形式如下

function Person () {
  this.name = 'little bear',
  this.age = 18
  setInterval(() => {
    console.log('我叫' + this.name + '我今年' + this.age + '岁')
},1000)
}
let p = new Person()

我们可以看到,箭头函数使用了定义时上下文的this,且与在哪里调用没有关系。

3.2 不绑定arguments
箭头函数还有一个比较有特点的地方就是其不绑定arguments,即如果你在箭头函数中使用arguments参数不能得到想要的内容。

let arrowfunc = () => console.log(arguments.length)
arrowfunc()
//output 
arguments is not defined

所以在箭头函数中我们是不能直接使用arguments对象的,但是如果我们又想获得函数的参数怎么办呢?
我们可以使用剩余参数来取代arguments剩余参数详情

let arrowfunc = (...theArgs) => console.log(theArgs.length)
arrowfunc(1,2)
//output
2

四 什么时候不能用箭头函数

前面我们已经看到了很多关于es6箭头函数的好处,也看到了箭头函数的一些不足。那么我们应该在什么时候使用箭头函数,而什么时候最好不要使用呢?
以下三种情况是不能使用箭头函数的:

1.作为构造函数,一个方法需要绑定到对象

<script>
    const Person = function(name, points) {
        this.name = name;
        this.points = points;
    }
    const Lucy = new Person('Lucy',5);
    Person.prototype.updatePoints = function() {
        this.points++;
        console.log(this.points)
    }

</script>

当我们用new生成一个Person的实例的时候其实要进行四个步骤:
1.生成一个新的对象
2.把构造函数里this的值指向新生成的对象
3.把这个对象绑定到它的原型对象
4.返回这个新生成的对象
但是我们通过这个箭头函数并没有实现把这个this值绑定到我们新生成的Lucy对象上去,所以并不会得到我们想要的效果,那么这个时候我们只能使用我们原始的函数。

2.当你真的需要this的时候

<script>

const button = document.querySelector('.zoom');
    button.addEventListener('click',function() {
        this.classList.add('in');
        setTimeout(() => {
            this.classList.remove('in');
        },2000)
    })
</script>

3.需要使用arguments对象

<script>

const sum = function() {
        return Array.from(arguments)
            .reduce((prevSum,value) => prevSum + value,0)
}
//在箭头函数当中是没有arguments这个对象的
</script>

五 总结

箭头函数由于其代码的简洁性和不绑定调用者this的特点,在非方法函数中使用是最合适的,而在方法函数中使用,需要特别注意它的this绑定问题,如果需要动态的修改this,最好还是不要使用箭头函数了。所以永远没有一个解决方案能解决所有事情,只有合适的应用场景。

转自:https://segmentfault.com/a/1190000009410939?utm_source=tag-newest

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值