在学习到箭头函数时,我们不禁要问:javascript 已经有了 function
函数,为什么 ES6 还要推出箭头函数?
经过反复研究和思考,得出一个结论:箭头函数的出现是为了消除 function
定义函数时带来的二义性。
function
的二义性表现
- 可以声明一个函数;
function fn() {
console.log('hello')
}
// 调用函数
fn() // hello
- 可以作为对象的构造器;
function Person() {
this.name = 'Tom'
this.age = 20
this.sex = '男'
return this
}
// 创建对象
const person = new Person()
console.log(person.name) // Tom
console.log(person.age) // 20
console.log(person.sex) // 男
funciton
既可以做函数声明,也可以做对象的构造器声明,这就带来了二义性,虽然不影响使用,但是在编程时容易出现问题,也增加了后期维护的复杂度。
单一职责
箭头函数的出现是为了消除function
二义性。箭头函数只做一件事,那就是定义函数,没有其他的作用。
同样为消除二义性所推出的还有 class
语法糖,只定义对象构造器,不作他用。
箭头函数与传统function
函数的差异
箭头函数与function
函数最大的差异就是:不具备作为构造器的能力。那么箭头函数就没有对象构造器相关的特点:
- 不能使用
new
关键字创建对象; - 不绑定
this
,因此使用call
,apply
,bind
并不会改变箭头函数中的this
指向; - 没有原型对象
prototype
;
此外还有其他的差异:
- 箭头函数更加简洁,在只有一行函数体时,可以省略括号和
return
关键字
const add = nun => num + 1
// 等价于
function add(num) {
return num + 1
}
- 箭头函数不绑定arguments,取而代之用rest参数解决
// function 函数调用 arguments
function fn() {
console.log(arguments)
}
fn(1,2,3) // [1,2,3]
// 箭头函数调用 arguments
const fn1 = () => console.log(arguments)
fn1(1,2,3) // 报错 Uncaught ReferenceError: arguments is not defined
// 箭头函数调用 rest
const fn2 = (...rest) => console.log(rest)
fn2(1,2,3) // [1,2,3]
编程实践
ps: 这只是我个人的编程习惯,不代表标准与普遍性。
在编程实践中,主要关注的是this
的指向和程序易读性。
- 在使用 vue2 时,由于
this
普遍存在,为了不造成混乱,一般使用箭头函数。 - 在非 vue2 框架和vu2框架下的非vue文件中,使用
function
声明函数,因为function
更易读,一看就是函数。 - 匿名函数、回调函数一般用箭头函数。
- 有时候函数调用出现在函数声明之前时,使用
function
声明函数,因为有变量提升机制,运行时可以把函数提升到作用域顶部。