JavaScript:箭头函数&剩余参数

简介: JavaScript:箭头函数&剩余参数

箭头函数

基本语法

箭头函数是一种声明函数的简洁语法,它与普通函数并无本质的区别,差异性更多体现在语法格式上。

  • 基本语法
//一般写法
function fn (a, b) {
  console.log(a, b);
}
//箭头函数形式
const fn = (a, b) => {
  console.log(a, b);
}

箭头函数的基本语法有以下特点:;

  1. 取消了function关键字
  2. 以赋值符号的形式将函数赋值给函数名
  3. 参数与函数体之间通过箭头=>衔接

就目前来看,箭头函数好像没有比一般函数简单多少,甚至好像更复杂了。

这是因为箭头函数可以根据不同的函数体,参数来省略语法,而一般的函数其形式是固定的。

接下来我带大家一一讲解箭头函数的省略语法:

  • 箭头函数的匿名
    匿名函数在JavaScript中应用非常广泛,主要是作为回调函数,此时函数不需要函数名也可以调用。
//一般写法
function (a, b) {
  console.log(a, b);
}
//箭头函数形式
(a, b) => {
  console.log(a, b);
}

匿名函数中,一般的函数语法,只能将函数名fn省略掉,而在箭头函数中,函数名是作为变量的,此时不仅仅可以省略掉函数名fn,还可以省略掉赋值符号=以及定义变量的关键字const/var/let。即整体省略掉:const fn =

到此为止,箭头函数就已经非常简约了,但是箭头函数在一些情况还可以更简单。

由于JavaScript中回调函数较多,我们后续的示例都以匿名函数形式。

  • 省略参数的小括号

当函数中只有一个参数,箭头函数可以省略小括号

这个语法可以省略掉参数的小括号,我们对比一下:

//一般写法
function (a) {
  console.log(a);
}
//箭头函数形式
(a) => {
  console.log(a);
}
//箭头函数缺省括号形式
a => {
  console.log(a);
}

但是要注意,这个缺省参数的括号,只能在只有一个参数的情况下使用,哪怕没有参数也不能缺省括号。

没有参数情况:

//箭头函数没有参数
() => {
  console.log(123);
}
  • 省略大括号

当函数体内部只有一条语句,可以省略大括号。

对比:

//一般写法
function (a, b) {
  console.log(a, b);
}
//箭头函数形式
(a, b) => {
  console.log(a, b);
}
//箭头函数省略大括号形式
(a, b) => console.log(a, b);

当然这种方法仅限于函数内部只有一条语句,此处的语句就是: console.log(a, b)。但是如果这条语句被写成:

(a, b) => {
  console.log(a);
  console.log(b);
}

这样的话,由于函数内部有两条语句,大括号就不能省略。

  • 省略return

上一个部分我们讲解了当函数内部只有一条语句,可以省略大括号。除此之外:

如果函数只有一条语句,且这个语句是return语句,那么可以同时省略大括号和return。

对比:

//一般写法
function (a, b) {
  return a + b;
}
//箭头函数形式
(a, b) => {
  return a + b;
}
//箭头函数省略大括号形式
(a, b) => return a + b;//这种写法是错的
//箭头函数省略大括号和return形式
(a, b) => a + b;

不过要注意(a, b) => return a + b这个写法是错的,在箭头函数省略大括号,且这一条语句是return时,return必须被省略

至此,我们就将箭头函数的最简洁语法展现给大家了。通过箭头函数的省略语法,在书写一些简单的函数时,可以以非常短的语句完成功能。这就是箭头函数的基本功能。

  • 返回字面量表达式

在函数中,如果我们返回的数据是一个对象,且只有一条返回语句,我们看看这个情况会带来什么误解:

//不省略的箭头函数返回对象
(a, b) => {
  return {uname: "张三"};
}
//省略大括号的箭头函数返回对象
(a, b) => return {uname: "张三"};//这种写法是错的
//省略return的箭头函数返回对象
(a, b) => {uname: "张三"};

着重看到这个语句:(a, b) => {uname: "张三"};请问: {uname: "张三"}的大括号是函数体的大括号,还是对象的大括号?

我们是程序的编写者,我们当然明确这个大括号属于对象,但是编译器并不能确定,这就会给编译器带来解析的错误。

所以为了避免这个错误,在使用缺省return的箭头函数返回对象时,要额外用一个小括号包起来

(a, b) => ({uname: "张三"});

其实箭头函数和普通函数的区别也不止语法的缺省。还有一些其它的注意事项。

箭头函数的this

箭头函数的this规则

在一般的函数中,只要谁调用这个函数,那么this就是谁。

在箭头函数中,箭头函数不会创建自己的this,而是从父级继承

给一个案例帮助理解:

const btn = document.querySelector("button");
//一般函数形式
btn.addEventListener("click", function() {
    this.style.display = "none";
})
//箭头函数形式
btn.addEventListener("click", () => this.style.display = "none")

在上述代码中,我们用两种函数书写了代码,其功能是:点击按钮btn后,按钮消失。

  • 分析第一段函数:
btn.addEventListener("click", function() {
    this.style.display = "none";
})

首先利用了btn调用函数addEventListener,然后再执行回调函数。

回调函数是被btn调用的,所以this就是btnthis.style.display = "none"语句就是把btn给隐藏,符合要求。

  • 分析第二段函数:
btn.addEventListener("click", () =>  this.style.display = "none")

这个函数中,回调函数是以箭头函数的形式,虽然回调函数被btn调用,但是其this会继承上一级的this,即全局作用域的window对象。那么 this.style.display = "none"就相当于 window.style.display = "none",此时不仅不能完成功能,还会报错。


箭头函数不能用于构造函数

我们看一段构造函数:

function Person(name,age){
    this.name = name;
    this.age = age;
}
const zhangsan = new Person("张三", 18);

由于构造函数要频繁使用this,而箭头函数没有自己的this,这就会导致其构造函数时出错。


箭头函数的换行

为了方便格式化,箭头函数提供了几种换行方法:

  • 在箭头后换行
const func = (a, b, c) =>
  1;
  • 如果省略了return,可以用小括号把返回值包起来
const func2 = (a, b, c) => (
  1
);
  • 如果没有省略return,就不能省略大括号
const func3 = (a, b, c) => {
  return 1;
};
  • 将参数换行
const func4 = (
  a,
  b,
  c,
) => 1;

箭头函数的参数绑定

在function定义的函数中,会存储一个argument对象,用于存储所有的参数(包括超出部分)。但是箭头函数并没有argument。所以箭头函数建议使用剩余参数来进行不定数量的参数传递。


在调用函数时,我们可能不知道用户会传几个参数进来,此时我们有两种方法解决问题,分别是动态参数与剩余参数。

动态参数

arguments 是函数内部内置的伪数组变量,它包含了调用函数时传入的所有实参。

<script>
  // 求生函数,计算所有参数的和
  function sum() {
    console.log(arguments)//[5, 10]  [1, 2, 4]
    let s = 0
    for(let i = 0; i < arguments.length; i++) {
      s += arguments[i]
    }
    console.log(s)
  }
  // 调用求和函数
  sum(5, 10)// 两个参数
  sum(1, 2, 4) // 两个参数
</script>

在上述代码中,我们调用了两次函数,第一次调用: sum(5, 10),那么argument = [5, 10]第二次调用sum(1, 2, 4)时,argument = [1, 2, 4]

但是这个arguement数组是一个伪数组,并不具备数组的一些方法,我们一般只对其读取内容


剩余参数

JavaScript中提供了一个符号...(展开运算符)。当其处于函数参数中时,会将剩余的参数整合为一个数组。

语法:

function fn(a, b, c, ...d){};

在上述语法中,d就是一个剩余参数。

我列举几个传参情况,帮助大家理解:

调用fn(1,2,3,4,5,6,7,8,9,10)

在fn中只有四个参数,abcd,此时abc按照顺序与参数匹配:

a = 1b = 2c = 3d = 4

多出来的5,6,7,8,9,10由于剩余参数d的存在,它们被整合为了一个数组:d= [5,6,7,8,9,10]

调用fn(1,2,3)

根据参数一一对应a = 1b = 2c = 3

那么d是什么呢?undefined吗?

并不是的,当剩余参数的变量没有匹配到参数时,其为一个空数组。

也就是d = []

此外,剩余参数还有以下注意特点:

  • 剩余参数是一个真数组,有数组的方法
  • 剩余参数可以在箭头函数中使用

在实际应用中,我们更推荐使用剩余参数代替argument。

相关文章
|
17小时前
|
JavaScript 前端开发
在JavaScript中,函数原型(Function Prototype)是一个特殊的对象
【5月更文挑战第11天】JavaScript中的函数原型是一个特殊对象,它为所有函数实例提供共享的方法和属性。每个函数在创建时都有一个`prototype`属性,指向原型对象。利用原型,我们可以向所有实例添加方法和属性,实现继承。例如,我们定义一个`Person`函数,向其原型添加`greet`方法,然后创建实例`john`和`jane`,它们都能调用这个方法。尽管可以直接在原型上添加方法,但推荐在构造函数内部定义以封装数据和逻辑。
10 2
|
17小时前
|
前端开发 JavaScript 数据处理
在JavaScript中,异步函数是指什么
【5月更文挑战第9天】JavaScript中的异步函数用于处理非立即完成的操作,如定时器、网络请求等。它们可通过回调函数、Promise或async/await来实现。示例展示了如何使用async/await模拟网络请求:定义异步函数fetchData返回Promise,在另一异步函数processData中使用await等待结果并处理。当fetchData的Promise解析时,data变量接收结果并继续执行后续代码。注意,调用异步函数不会阻塞执行,而是会在适当时间点继续。
11 0
|
17小时前
|
自然语言处理 JavaScript 前端开发
在JavaScript中,this关键字的行为可能会因函数的调用方式而异
【5月更文挑战第9天】JavaScript中的`this`关键字行为取决于函数调用方式。在非严格模式下,直接调用函数时`this`指全局对象,严格模式下为`undefined`。作为对象方法调用时,`this`指向该对象。用`new`调用构造函数时,`this`指向新实例。通过`call`、`apply`、`bind`可手动设置`this`值。在回调和事件处理中,`this`可能不直观,箭头函数和绑定方法可帮助管理`this`的行为。
11 1
|
16小时前
|
JavaScript 前端开发 网络架构
JavaScript中的箭头函数是一种新的函数表达形式
【5月更文挑战第9天】JavaScript的箭头函数以简洁语法简化函数定义,其特性包括:1) 不绑定自身this,继承上下文的this,适合回调和事件处理;2) 没有arguments对象,需用剩余参数语法访问参数;3) 不能用作构造函数,无new调用;4) 没有prototype属性,不支持基于原型的继承。箭头函数在特定场景下优化了this处理,但使用时要注意与普通函数的差异。
11 2
|
16小时前
|
JavaScript 前端开发
js的一些内置函数
js的一些内置函数
7 1
|
17小时前
|
JavaScript 前端开发 索引
js的includes函数
js的includes函数
13 1
|
16小时前
|
JavaScript 安全 前端开发
js的map函数
js的map函数
7 0
|
17小时前
|
JavaScript 前端开发
js的filter函数
js的filter函数
10 1
|
17小时前
|
JavaScript 前端开发
js的函数
js的函数
9 0
|
17小时前
|
JavaScript 前端开发
js的join函数
js的join函数
9 1