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