前言:在上一篇文章我们了解到了一些面试中经常被问到的ES6+的新特性,面试官问完ES6+的新特性后,经常会接着追问你让你讲一下箭头函数与普通函数的区别。许多人都不能答全,接下来让我们来深入了解下箭头函数究竟是何方神圣?
当面试官问箭头函数与普通函数的区别时,我们可以从以下几个方面来回答
1. 语法层面
- 简洁性 :箭头函数语法更加简洁。对于单个参数,可省略括号;若函数体只有一条语句,还能省略花括号和
return
关键字。比如:
js
// 箭头函数
const square = num => num * num;
// 普通函数
function squareFunction(num) {
return num * num;
}
- 参数定义 :普通函数使用
function
关键字定义,参数在括号内。而箭头函数使用=>
来分隔函数和函数体。
2. this指向
- 普通函数 :
this
的指向取决于函数的调用方式。它可以指向全局对象(在浏览器中是window
)、函数本身、对象实例、或者构造函数等。例如:
js
const obj = {
name: 'Alice',
sayName: function () {
console.log(this.name);
}
};
obj.sayName(); // 输出 'Alice',this 指向 obj
function test() {
console.log(this);
}
test(); // 在浏览器中输出 window 对象, 在 Node.js 中输出 global 对象
- 箭头函数 :没有自己的
this
,它的this
继承自外层函数。这能避免在嵌套函数中this
指向改变的问题。例如:
js
const obj = {
name: 'Bob',
sayName: function () {
const arrow = () => {
console.log(this.name);
};
arrow();
}
};
obj.sayName(); // 输出 'Bob',this 继承自外层的 sayName 函数
3. arguments对象
- 普通函数 :有自己的
arguments
对象,它是一个类数组对象,包含了函数调用时传递的所有参数。例如:
js
function showArgs() {
console.log(arguments);
}
showArgs(1, 2, 3); // 输出 Arguments(3) [1, 2, 3]
- 箭头函数 :没有自己的
arguments
对象。若要获取参数,可以使用剩余参数语法。例如:
js
const showArgsArrow = (...args) => {
console.log(args);
};
showArgsArrow(4, 5, 6); // 输出 [4, 5, 6]
4. 构造函数使用
- 普通函数 :可以作为构造函数,使用
new
关键字创建对象实例。例如:
js
function Person(name) {
this.name = name;
}
const person = new Person('Charlie');
console.log(person.name); // 输出 'Charlie'
- 箭头函数 :不能用作构造函数,使用
new
关键字调用箭头函数会报错。因为箭头函数没有自己的this
和prototype
,无法创建对象实例。例如:
js
const ArrowPerson = (name) => {
this.name = name;
};
try {
const arrowPerson = new ArrowPerson('David'); // 会抛出错误
} catch (error) {
console.error(error);
}
5. yield关键字使用
- 普通函数 :在生成器函数中可以使用
yield
关键字,用于暂停和恢复函数的执行。例如:
js
function* generator() {
yield 1;
yield 2;
yield 3;
}
const gen = generator();
console.log(gen.next().value); // 输出 1
- 箭头函数 :不能使用
yield
关键字,所以不能用作生成器函数。