常规函数和箭头函数之间的主要区别
在 JavaScript
中,函数是设计用于执行特定任务的代码块。函数允许使用函数将大型程序分解为多个更小、更易于管理的组件。因此,我们就不再需要重复编写相同的代码。
JavaScript
中有两种类型的函数
- 常规函数
- 箭头函数(
ES6
中引入)
常规函数
我们可以通过两种方式编写常规函数,即函数声明和函数表达式。
// 函数声明
function add(a, b) {
return a + b;
}
const sum = function (a, b) {
return a + b;
};
add(1, 2);
sum(1, 2);
函数声明和函数表达式之间的主要区别是我们也可以在声明(具体可以查看这篇js 变量提升和函数提升)之前调用函数add(1,2)
,但是 函数sum(1,2)
需要在定义之后调用。
箭头函数
箭头函数是 ES6
中引入的新特性,它是编写函数表达式的更简洁的语法。与常规函数相比,它允许我们更清晰地创建函数。它没有函数声明的方式,我们可以只使用函数表达式来编写。
// 箭头函数表达式
const add = (a, b) => {
return a + b;
};
// 更简洁的方式
const add = (a, b) => a + b;
箭头函数和常规函数有一定的区别,即
- 语法
- 无
arguments
对象(arguments
是类似数组的对象) - 箭头函数没有原型对象
- 无法使用
new
关键字调用(不是构造函数) - 没有
this
对象(call
、apply
和bind
将无法按预期生效) - 它不能用作生成器函数
- 不允许重复命名的参数
下面我们来逐个讲解
区别
语法
如果仅存在一个表达式,则不需要大括号,并且它将隐式从函数返回此结果。这使得代码更清晰。
const add = (a, b) => a + b;
const square = a => a * a;
无arguments
如果函数的参数数量未知,我们可以将所有参数作为单个变量获取,即arguments
。参数对象看起来像这样:
function getAllParameters() {
console.log(arguments);
}
getAllParameters(1, 'args', {a: 1}, true)
arguments
是一个类似数组的对象。类数组对象和数组对象之间的相似之处在于它们都具有长度属性。不同的是,类数组对象没有数组的内置方法,但是我们可以使用Array.from
将类数组对象转换为数组对象。
function getAllParameters() {
console.log(arguments);
console.log(Array.from(arguments));
}
在箭头函数中,没有任何参数,如果我们在箭头函数中访问参数,将会抛出类似Uncaught ReferenceError: arguments is not Defined
的错误。
const getAllParameters = () => {
console.log(arguments);
}
getAllParameters(1, 'args', {a: 1}, true)
但我们可以使用剩余参数(...
)来代替,它得到一个普通的数组对象。
const getAllParameters = (...args) => {
console.log(args);
}
getAllParameters(1, 'args', {a: 1}, true)
箭头函数没有原型对象
箭头函数没有像常规函数那样的原型对象,如果尝试访问箭头函数的原型,它将返回undefined
。
function regular() {}
const arrayFn = () => {}
console.log(regular.prototype);
console.log(arrayFn.prototype);
无法使用 new 关键字调用
箭头函数不能用 new
关键字调用,因为箭头函数没有构造函数。如果尝试使用new
关键字实例化,则会抛出错误。
const arrayFn = () => {}
const obj = new arrayFn();
没有this对象
在常规函数中,它的内部this
值是动态的,它取决于函数如何被调用。例如:
function regular() {
console.log(this);
}
const obj = {
getThis: regular
}
regular();
obj.getThis();
与常规函数不同,箭头函数没有自己的this绑定。如果我们在箭头函数中访问this
,它将返回最近的非箭头父函数的this
。
const arrayFn = () => {
console.log(this);
}
const obj = {
getThis: arrayFn
}
arrayFn();
obj.getThis();
箭头函数中 this
的值在声明时确定,并且永远不会改变。所以call
, apply
,bind
不能改变箭头函数的this
。
不能用作生成器函数
function*
语句(function
关键字后跟星号)定义了一个生成器函数。
Yield
关键字不能用在箭头函数的主体中(除非在进一步嵌套的函数中允许使用)。因此,箭头函数不能用作生成器。
const arrayGenerator = *() => {}
不允许重复命名的参数
在非严格模式下,常规函数允许我们使用重复的命名参数。但在严格模式下,是不允许的。
function add(a, a) {
return a + a;
}
function add(a, a) {
console.log('replace');
return a + a + 10;
}
add(1, 2)
"use strict"
function add(a, a) {
return a + a;
}
function add(a, a) {
console.log('replace');
return a + a + 10;
}
add(1, 2)
与常规函数不同,箭头函数不允许重复参数,无论是在严格模式还是非严格模式。重复的参数将导致抛出语法错误。
const add = (a, a, a) => {
console.log(a)
}