JavaScript

ES6箭头函数的使用

总结了箭头函数与普通函数的区别以及使用

Yixuan Lang
2021-06-03
2 min

# ES6箭头函数及使用场景

在ES6之前,我们通常会使用函数表达式或者函数声明的方式来定义函数。ES6中在函数部分新增了一个特性就是箭头函数。可以使用=>的方式来定义函数。这种方式使得函数定义的写法更加简洁,箭头函数内部的this指向与普通函数有所区别,也使得箭头函数可以灵活的在一些场景下使用。该篇文章对如何使用箭头函数以及其使用场景做出了总结。

arrow function

# 一、箭头函数的使用


// 普通函数的定义
var fn = function() {
    return res
}
// 箭头函数的定义
var fn = () => { return res }
  • 当函数只接收一个参数,并且直接返回结果时,可以省略()和{ }
var fn = function(arg1) {
	return res
}
// 箭头函数可以简写为
var fn = args1 => res
  • 箭头函数与变量解构结合使用
const full = ({ first, last }) => fitst + '' + last
// 等同于
const full = function(person) {
    return person.first + '' + person.last
}
  • 箭头函数结合rest参数使用
const numebers = (...nums) => nums
numbers(1, 2, 3, 4)
// 返回结果[1, 2, 3, 4]

const headAndTail = (head, ...tail) => [head, tail]
headAndTail(1, 2, 3, 4, 5)
// 返回结果:[1, [2, 3, 4, 5]]
  • 箭头函数相当于匿名函数,非常适合用于简化回调函数
[1, 2, 3].map(function(x){
    return x * x
})
// 箭头函数简化回调
[1, 2, 3].map(x => x * x)

# 二、箭头函数与普通函数的区别


# 1. 箭头函数没有自己的this

普通函数的this指向取决于其函数的调用者,箭头函数不会创建自己的this,而是从自身的作用域链的上一层继承this。也就是说箭头函数在定义时会继承外层执行环境的this; 箭头函数的this指向在被定义的时候就已经确定了,之后不会再改变。

function foo() {
	setTimeout(() => {
        console.log('id', this.id)
    }, 100)
}

function foo2() {
    setTimeout(function() {
        console.log('id', this.id)
    }, 100)
}
var id = 21
foo.call({ id: 42 })  // id: 42
foo2.call({ id: 42 })  // id: 21

foo函数内部的定时器回调是通过箭头函数的方式定义,其函数的this会继承外层执行环境也就是foo函数的this。

# 2. call()/.apply()/.bind()无法改变箭头函数中this的指向

.call()/.apply()/.bind()方法可以用来动态修改函数执行时this的指向,但由于箭头函数的this定义时就已经确定且永远不会改变。所以使用这些方法永远也改变不了箭头函数this的指向,虽然这么做代码不会报错

var id = 'Global';
// 箭头函数定义在全局作用域
let fun1 = () => {
    console.log(this.id)
};

fun1();     // 'Global'
// this的指向不会改变,永远指向Window对象
fun1.call({id: 'Obj'});     // 'Global'
fun1.apply({id: 'Obj'});    // 'Global'
fun1.bind({id: 'Obj'})();   // 'Global'

# 3. 箭头函数没有自己的arguments

除了this,arguments、super、new.target三个变量在函数中也是不存在的,在箭头函数中访问arguments实际上获得的是外层局部(函数)执行环境中的值。

function foo() {
	setTimeout(() => {
        console.log('args:', arguments )
    }, 100)
} 
foo(2, 4, 6, 8)
// 输出结果: [2, 4, 6, 8]

# 4. 箭头函数不能当作构造函数使用

构造函数需要使用new关键字进行调用,在调用时会有将函数内部的this指向实例对象的操作。但是箭头函数根本没有自己的this,所以不能当作构造函数来使用

let Fun = (name, age) => {
    this.name = name;
    this.age = age;
};

// 报错
let p = new Fun('cao', 24);

# 5. 箭头函数没有原型prototype

let sayHi = () => {
    console.log('Hello World !')
};
console.log(sayHi.prototype); // undefined