谈谈function函数和箭头函数

前言

function函数和箭头函数算是一个老生常谈的问题了,从我刚接触javaScript的时候就被告知,不要直接使用function,直接用箭头函数,这样能避免80%的问题,实际使用过程中也确实是这样,在各种错综复杂的函数回调中,如果不使用箭头函数,会导致this指向错乱,程序各种报错。(当然也可以使用call之类的Function函数去改变this指向,不够这样大大加深了操作成本)

今年难得有空摸个鱼就想来聊一聊这个话题,也帮自己理一下思路。

区别

function和箭头函数最直观的区别就是创建方法不同

// function函数创建
function A() {
    console.log(this)
}
B = function () {
    console.log(this)
}

// 箭头函数创建
C = () => {
    console.log(this)
}

接下来就是常说的this指向问题了,以下都是不考虑call、bind、apply的情况:

  • function函数的this是使用时指定。(创建function函数时,this是undefined,只有在函数被调用的时候,this指向调用者)
  • 箭头函数的this是创建时指定。(当箭头函数被创建的时候,会根据当前上下文来bind当前的this,函数在之后的调用过程中,都能访问到创建该函数的上下文)

我们使用浏览器的控制台进行调试

// 执行function A时,控制台输出this指向window 
A()
// 执行objectB.b时,控制台输出this指向{b: ƒ}
objectB = { b: B }
objectB.b()

// 执行箭头函数 C时,控制台输出this指向window 
C()
// 执行objectC.c时,控制台输出this指向window 
objectC = { c: C }
objectC.c()

上面的例子能很好的看出来,function函数的this指向它的调用者,而箭头函数的this指向与调用者无关。

对象创建

我们明白在js里,可以 new function函数来创建对象,但是不能 new 箭头函数来创建对象。

// 使用 new  function A 来创建对象,能得到继承A的原型链的的一个新对象
new A()
// 报错:Uncaught TypeError: C is not a constructor
new C()

为什么同样是函数,但是却不能通过 new 箭头函数来创建对象呢?

其实之前的例子可以看出,function函数是没有指定对象的,根据js使用 new function函数来创建对象的规则(先创建空对象,用空对象执行function函数,然后该对象继承function函数的原型链,最后返回该对象)不难看出,对于创建时就绑定了this指向的箭头函数来说,是没法使用new关键字来创建的。

虽然我们不能通过 new 箭头函数来创建对象,但是我们可以通过后面完善的Object的Prototype函数来创建对象

// 用第一个对象参数,执行完箭头函数后,该对象继承function函数的原型链,最后返回该对象
Object.create({},C)

总结

不难看出,function函数的初衷就是为了创建对象,所以我们用function函数来当普通函数在web端调用的时候,很容易出现各种问题,而后面出现的箭头函数极大的解决了这个问题。 所以,我建议在之后的代码编写中,当需要使用创建对象的时候,使用function函数,而仅仅需要当做执行方法时,用箭头函数。这样写起代码来思路很更加清晰。

后记

不过话说回来,现在有es6的语法,可以说,梭哈箭头函数就行,把function函数丢进历史的长河里吧。(仅个人见解,求生欲极强)