lxinr/interview-question

箭头函数和普通函数之间的区别

Opened this issue · 1 comments

lxinr commented

语法不同

箭头函数更加简洁

普通函数

const arr = [1, 2, 3, 4]
const newArr = arr.map(function(item, index) {
  return ++item
})

箭头函数

const arr = [1, 2, 3, 4]
const newArr = arr.map((item, index) => {
  return ++item
})
// 如果只有一个参数,可以简写成
const newArr = arr.map(item => {
  return ++item
})
// 甚至可写成一行
const newArr = arr.map(item => ++item)

不绑定this

箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this

function Parent() {
  this.name = 'lx';

  setTimeout(function() {
    console.log(this.name) // undefined
  }, 0)

  setTimeout(() => {
    console.log(this.name) // lx
  }, 0)
}

const p = new Parent()

箭头函数在使用call、apply、bind时只能传参,无法绑定this,即第一个参数会忽略

const parent = {
  num : 1,
  func: function(a) {
    const f = function(v) {
      return v + this.num
    }
    const obj = { num: 2 }
    return f.call(obj, a) 
  },
  arrowFunc: function(a) {
    const f = v => v + this.num
    const obj = { num: 2 }
    return f.call(obj, a)
  }
};

console.log(parent.func(1))         // 输出 3
console.log(parent.arrowFunc(1))    // 输出 2

箭头函数不绑定arguments

箭头函数不绑定Arguments对象,如果需要在箭头函数中使用类似于arguments的方法,可以选择使用剩余参数的方式(...args)

// 箭头函数使用剩余参数
const arrowFunc = (...args) => args.join(',')
console.log(arrowFunc(1,2,3,4,5)) // 1,2,3,4,5

箭头函数不能使用new操作符

箭头函数不能用作构造器,和new一起用会抛出错误

const Func = a => ++a
const func = new Func() // Uncaught TypeError: Func is not a constructor

箭头函数没有prototype属性

const func = function() {}
console.log(func.prototype) // {constructor: ƒ}

const func1 = () => {}
console.log(func1.prototype) // undefined

箭头函数不能用作生成器

yield关键字通常不能在箭头函数中使用(除非是嵌套在允许使用的函数内)。因此,箭头函数不能用作生成器。

lxinr commented

总结

箭头函数表达式的语法比函数表达式更短,并且不绑定自己的this,arguments,super或 new.target。这些函数表达式最适合用于非方法函数(non-method functions),并且它们不能用作构造函数

  1. 箭头函数没有this,在箭头函数中访问的this实际来自于外部词法环境
  2. 箭头函数没有arguments
  3. 箭头函数不能使用new进行调用
  4. 箭头函数没有super
  5. 箭头函数没有原型