今天来说说箭头函数

398 阅读2分钟

这是我参与8月更文挑战的第7天,活动详情查看:8月更文挑战

前言

es6标准还没出来之前,我们一直使用的是普通函数

就比如下面写法:

function fn () {
  console.log('你好,我是答案cp3!')
}
fn() // 你好,我是答案cp3!

es6标准出来后,增加了箭头函数(Arrow Function),今天来讲讲它和普通函数的区别。

箭头函数

语法:

(args1,args2) => {return xxx}

对比普通函数,去掉了function, 替换成了=>

普通函数定义的方式有两种:一种是函数声明,另一种是函数表达式

// 函数声明
function fn () {}

// 函数表达式
let fn = function () {}

箭头函数只能使用函数表达式

let fn = () => {}

写法还有以下区别:

  • 如果只有一个参数,可以省略括号
  • =>后面的语句如果可以直接return的话,可以省略{}return
let fn = (a) => { return a } 
// 可以写成
let fn = a => { return a } 

// 还可以改写成
let fn = a => a

这三个函数运行效果时一样的。对比普通函数,箭头函数写法是相对简洁一点。

下面继续讲讲它在用法上跟普通函数的区别。

  1. 箭头函数没有创建自己的this,而是继承了它在定义时上层作用域的this,并且后面不会再次改变。

    var obj = {
      fn: function() {
        console.log(this)
      }
    }
    obj.fn() // obj对象
    
    var obj = {
      fn: () => {
        console.log(this)
      }
    }
    obj.fn() // window对象
    

    从以上例子可以看出,

    调用普通函数时,它的this指向调用时所处的对象,此时是obj

    而调用箭头函数时,它的this指向是定义时上层的作用域的this,因为我是在chrome的控制台运行的,这时上层的作用域的this是指向window,所以打印出window对象。

  2. 由于箭头函数的this一旦定义后就无法改变,所以applycall, bind等方法无法改变箭头函数的指向。

    let fn = function() {console.log(this)}
    fn.call({a:123}) // ({a:123}
    
    let fn = () => {console.log(this)}
    fn.call({a:123}) // window对象
    
  3. 因为箭头函数内部没有自己的this,所以也就不能用作构造函数

    let fn = function () {}
    new fn() // fn实例
    
    let fn = () => {}
    new fn() // Uncaught TypeError: fn is not a constructor
    
  4. 箭头函数内部没有arguments对象

    let fn = function() {console.log(arguments)}
    fn() // Arguments [callee: ƒ, Symbol(Symbol.iterator): ƒ]
    
    let fn = () => {console.log(arguments)}
    fn() // Uncaught ReferenceError: arguments is not defined
    
  5. 箭头函数没有prototype属性

    let fn = function() {}
    console.log(fn.prototype) // {constructor: ƒn}
    
    let fn = () => {}
    console.log(fn.prototype) // undefined
    
  6. 箭头函数内部不可以使用yield命令,因此箭头函数不能用作Generator函数。

    let fn = function *() {
     yield '答案cp3'
    }
    let fn1 = fn()
    fn1.next() // {value: "答案cp3", done: false}
    
    let fn = *() => {
     yield '答案cp3'
    }
    let fn1 = fn()
    fn1.next() // Unexpected token '*'
    

总结

以上就是我总结的箭头函数的使用,箭头函数和普通函数还是有很大区别。

不同的场景上选择使用不同的函数,大家可以自由选择。