箭头函数与普通函数的区别

前言

箭头函数和普通函数相比有什么区别?这是一道高频面试题。箭头函数用起来很香,但许多人对它的理解还不够深入,很容易就被考倒。认真看完这篇文章,相信你会有一个更清晰的认知。

定义方式

普通函数

定义普通函数的方式通常有函数声明和函数表达式:

// 函数声明
function test() {
    
}

// 函数表达式
const test = function () {};

箭头函数

箭头函数是普通函数的语法糖,书写要更加简洁:

const test = () => {};

this指向

普通函数

严格模式下,this指向undefined

"use strict"

function test() {
    console.log(this); // undefined
}

非严格模式下,this指向window

function test() {
    console.log(this); // window
}

谁调用函数,函数内部的this就指向谁:

const obj = {
    x: 1,
    fn: function () {
        console.log(this); // obj
    },
};

obj.fn();

普通函数中的this指向是动态的:

function fn() {
    console.log(this); // obj
}

const obj = {
    x: 1
};

const fn1 = fn.bind(obj);
fn1();

上栗中,fn 函数中的this本应指向window,后面我们通过bind方法将函数的this指向改变为了 obj 对象,所以打印出 obj。

可以看出,普通函数的this指向可以通过bindcallapply等方法进行改变,this指向是动态的。

箭头函数

无论是严格模式还是非严格模式下,this始终指向window

"use strict"

const test = () => {
    console.log(this); // window
};
const test = () => {
    console.log(this); // window
};

箭头函数没有自己的执行上下文,this指向是在定义函数时就被确定下来的,箭头函数中的this,永远指向外层作用域中最接近自己的普通函数的this

const obj = {
    x: 1,
    fn: function () {
        console.log(this); // obj
        const test = () => {
            console.log(this); // obj
        };
        test();
    }
};

obj.fn();

上栗中,普通函数 fn 作为 obj 的属性被调用,谁调用普通函数,那么函数中的this就指向谁,所以 fn 的this指向 obj。

fn 函数内部有一个箭头函数 test,test 没有自己的this,它的this指向外层作用域中最接近自己的普通函数的this,所以 test 中的this也指向 obj。

箭头函数会忽略任何形式的this指向的改变,箭头函数的this指向是静态的:

const obj = {
    x: 1,
}

const fn = () => {
    console.log(this); // window
};

const fn1 = fn.bind(obj);
fn1();

bindcallapply等方法无法改变箭头函数的this指向。

构造函数

普通函数

通过new关键字调用普通函数(作为构造函数),this指向被创建出来的对象实例:

function fn(name, age) {
  this.name = name;
  this.age = age;
  console.log(this); // {name: '吴彦祖', age: 18}
}

new fn("吴彦祖", 18);

箭头函数

箭头函数不能当做构造函数来使用:

const test = () => {};
new test(); // error: test is not a constructor

arguments 对象

普通函数

在普通函数中,arguments是类数组对象,保存着函数执行时传入的参数:

function fn(x, y) {
    console.log(arguments); // {0: 1, 1: 2, length: 2}
}

fn(1, 2);

箭头函数

箭头函数没有arguments

const test = (x, y) => {
    console.log(arguments); // error: arguments is not defined
};

test(1, 2);

补充

  • 箭头函数没有prototype属性
  • 箭头函数不能当做Generator函数,不能使用yield关键字
  • 箭头函数不能被new关键字调用,不具有new.target

最后

如果文中有错误或者不足之处,欢迎大家在评论区指正。

你的点赞是对我莫大的鼓励!感谢阅读~