前言
箭头函数和普通函数相比有什么区别?这是一道高频面试题。箭头函数用起来很香,但许多人对它的理解还不够深入,很容易就被考倒。认真看完这篇文章,相信你会有一个更清晰的认知。
定义方式
普通函数
定义普通函数的方式通常有函数声明和函数表达式:
// 函数声明
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指向可以通过bind、call、apply等方法进行改变,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();
bind、call、apply等方法无法改变箭头函数的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
最后
如果文中有错误或者不足之处,欢迎大家在评论区指正。
你的点赞是对我莫大的鼓励!感谢阅读~