一、书写格式
1. 箭头函数
- 只有一个参数,小括号可以省略;没有参数时括号不能省略
- 函数体中只有一行代码时,大括号可以省略;返回值为对象类型时,需要用 () 括起来
const fn = () => {}
const fnReturnObject = () => ({})
2. 普通函数
function fn() {}
二、参数
1. 箭头函数
- rest参数… (真数组)
const fn = (...args) => console.log(args) // fn(1, 2, 3) -> [ 1, 2, 3 ]
2. 普通函数
- arguments (伪数组)
function fn() {
console.log(arguments)
}
// fn(1, 2, 3) -> [Arguments] { '0': 1, '1': 2, '2': 3 }
三、this指向
1. 箭头函数
- this指向上层函数作用域的this对象,如果没有上层函数作用域,则指向顶部 this (在浏览器中顶部 this 则是 window)
const fn = () => console.log(this) // fn() -> Window
2. 普通函数
- this指向该函数的调用者
const obj = {
fn() {
console.log(this)
}
}
// obj.fn() -> {fn: ƒ} (obj)
3. call, apply, bind 修改 this 指向
- call、apply、bind 会改变普通函数的 this,但不会改变箭头函数的 this
const obj = {
a: 1
}
function fn1 () {
console.log(this.a)
}
// fn1.call(obj) -> 1
// fn1.apply(obj) -> 1
// fn1.bind(obj)() -> 1
const fn2 = () => console.log(this.a)
// fn2.call(obj) -> undefined
// fn2.apply(obj) -> undefined
// fn2.bind(obj)() -> undefined
四、原型和构造函数
1. 箭头函数
- 不能使用 new 生成实例,因为箭头函数没有 prototype,而 construct 在 prototype 里面
const fn = () => {}
// const f = new fn() -> TypeError: fn is not a constructor
// console.log(fn.prototype) -> undefined
2. 普通函数
function fn() {}
// const f = new fn() -> {}
// console.log(fn.prototype) -> {constructor: ƒ}
五、变量提升
1. 箭头函数
- 使用 let、const 定义箭头函数,不会变量提升
fn() // ReferenceError: fn is not defined
let fn = () => {}
// const fn = () => {}
- 使用 var 定义箭头函数,变量提升,但没有初始化
fn() // TypeError: fn is not a function
var fn = () => {}
2. 普通函数
- 普通函数在定义之前能够正常调用
fn() // 'fn called'
function fn() {
console.log('fn called')
}
六、其他
- 箭头函数内不能用 yield 且不能用作 Generator 函数,而普通函数可以。
- … …