es6知识点3-自备使用

7. 剩余参数 ...args

刚刚已经学过:

js 复制代码
const newUser = {
  ...user
}

这里的 ... 是"展开"。

但如果 ... 出现在函数参数位置,意思就变了,叫:

剩余参数

例如:

js 复制代码
function sum(...nums) {
  console.log(nums)
}

sum(1, 2, 3)

输出:

js 复制代码
[1, 2, 3]

这里:

js 复制代码
...nums

意思是:

把传进来的剩余参数全部收集起来,组成一个数组。


7.1 为什么需要它

假设你不知道调用者会传几个数字:

js 复制代码
sum(1, 2)

sum(1, 2, 3)

sum(1, 2, 3, 4, 5)

就可以:

js 复制代码
const sum = (...nums) => {
  let total = 0

  nums.forEach(num => {
    total += num
  })

  return total
}

调用:

js 复制代码
console.log(sum(1, 2, 3))
// 6

7.2 前面可以有固定参数

例如:

js 复制代码
function test(name, ...scores) {
  console.log(name)
  console.log(scores)
}

test('张三', 80, 90, 95)

结果:

text 复制代码
张三

[80, 90, 95]

这里:

js 复制代码
name

拿第一个参数。

剩下的:

js 复制代码
80, 90, 95

全部进入:

js 复制代码
scores

所以:

js 复制代码
scores = [80, 90, 95]

7.3 ... 一定要放最后

正确:

js 复制代码
function test(name, ...args) {
}

错误:

js 复制代码
function test(...args, name) {
}

因为 JavaScript 不知道"剩余参数"到底应该收到哪里结束。


7.4 展开和剩余怎么区分

这是重点。

看位置。

展开

js 复制代码
const arr2 = [...arr1]

意思:

把 arr1 拆开。


剩余

js 复制代码
function test(...args) {
}

意思:

把剩余参数收集起来。

可以记:

text 复制代码
放在数据里面 → 展开

放在函数参数里面 → 收集

例如:

js 复制代码
const arr = [1, 2, 3]

console.log(...arr)

相当于:

js 复制代码
console.log(1, 2, 3)

而:

js 复制代码
const test = (...args) => {
  console.log(args)
}

是反过来:

text 复制代码
1, 2, 3
↓
[1, 2, 3]

8. 函数默认参数

以前写 JavaScript,经常会这样:

js 复制代码
function getList(pageNum, pageSize) {
  if (pageNum === undefined) {
    pageNum = 1
  }

  if (pageSize === undefined) {
    pageSize = 10
  }
}

ES6 可以直接:

js 复制代码
function getList(pageNum = 1, pageSize = 10) {
  console.log(pageNum, pageSize)
}

调用:

js 复制代码
getList()

结果:

text 复制代码
1 10

调用:

js 复制代码
getList(2)

结果:

text 复制代码
2 10

调用:

js 复制代码
getList(2, 20)

结果:

text 复制代码
2 20

8.1 实战:分页参数

你做后台项目很常见:

js 复制代码
const getOrderList = (pageNum = 1, pageSize = 10) => {
  return request({
    url: '/xxx/order/list',
    method: 'get',
    params: {
      pageNum,
      pageSize
    }
  })
}

调用:

js 复制代码
getOrderList()

默认:

text 复制代码
pageNum = 1
pageSize = 10

也可以:

js 复制代码
getOrderList(3, 50)

8.2 默认参数和解构一起用

这种写法很实用:

js 复制代码
function search({
  pageNum = 1,
  pageSize = 10,
  status = ''
}) {
  console.log(pageNum)
  console.log(pageSize)
  console.log(status)
}

调用:

js 复制代码
search({
  status: 'COMPLETED'
})

结果:

text 复制代码
pageNum = 1
pageSize = 10
status = COMPLETED

这里其实同时用了:

text 复制代码
解构赋值
+
默认参数

8.3 再保险一点

有时候调用:search() 会报错。

因为相当于在对:undefined 进行对象解构。

所以实际可以这样:

js 复制代码
function search({
  pageNum = 1,
  pageSize = 10,
  status = ''
} = {}) {
}

注意最后:

js 复制代码
= {}

这表示:

如果整个参数都没传,就先给一个空对象。

所以:

js 复制代码
search()

也不会报错。

这个写法在工具函数、公共函数里很实用。


9. 数组常用方法

这一块非常重要。

先记住 5 个:

text 复制代码
map
filter
find
some
every

另外还有两个你肯定也会用:

text 复制代码
forEach
reduce

但我们先把核心 5 个讲明白。

假设有一组用户数据:

js 复制代码
const users = [
  {
    id: 1,
    name: '张三',
    age: 18,
    enabled: true
  },
  {
    id: 2,
    name: '李四',
    age: 25,
    enabled: false
  },
  {
    id: 3,
    name: '王五',
    age: 30,
    enabled: true
  }
]

9.1 map:把每一项转换成另一种东西

例如现在只想拿姓名:

js 复制代码
const names = users.map(item => item.name)

结果:

js 复制代码
['张三', '李四', '王五']

你可以理解成:

text 复制代码
原数组
↓
逐个加工
↓
生成新数组

所以:

js 复制代码
map

特别适合:

数据转换。


实战案例

后端返回:

js 复制代码
const users = [
  { id: 1, name: '张三' },
  { id: 2, name: '李四' }
]

前端下拉框需要:

js 复制代码
[
  {
    label: '张三',
    value: 1
  },
  {
    label: '李四',
    value: 2
  }
]

可以:

js 复制代码
const options = users.map(item => {
  return {
    label: item.name,
    value: item.id
  }
})

还可以简写:

js 复制代码
const options = users.map(item => ({
  label: item.name,
  value: item.id
}))

注意这里有个小知识:

js 复制代码
item => ({
})

为什么对象外面多一层括号?

因为:

js 复制代码
item => {
}

JavaScript 会把 {} 当成函数体。

所以如果想直接返回对象,要:

js 复制代码
item => ({
})

9.2 filter:过滤数据

假设只要启用用户:

js 复制代码
const enabledUsers = users.filter(item => item.enabled)

结果:

js 复制代码
[
  {
    id: 1,
    name: '张三',
    age: 18,
    enabled: true
  },
  {
    id: 3,
    name: '王五',
    age: 30,
    enabled: true
  }
]

如果只要年龄大于 20:

js 复制代码
const result = users.filter(item => item.age > 20)

得到:

text 复制代码
李四
王五

所以:

text 复制代码
filter = 筛选

Vue 实战

例如:

js 复制代码
this.tableData = response.rows.filter(item => item.status !== 'CANCELLED')

意思:

把所有取消状态的数据排除掉。


9.3 find:找到第一条符合条件的数据

例如:

js 复制代码
const user = users.find(item => item.id === 2)

得到:

js 复制代码
{
  id: 2,
  name: '李四',
  age: 25,
  enabled: false
}

注意:

js 复制代码
find

返回的是:

一条数据。

而:

js 复制代码
filter

返回的是:

一个数组。

这是两者最核心的区别。


对比一下

js 复制代码
const result1 = users.filter(item => item.id === 2)

得到:

js 复制代码
[
  {
    id: 2,
    name: '李四'
  }
]

是数组。

而:

js 复制代码
const result2 = users.find(item => item.id === 2)

得到:

js 复制代码
{
  id: 2,
  name: '李四'
}

直接就是对象。


没找到怎么办

js 复制代码
const user = users.find(item => item.id === 100)

结果:

js 复制代码
undefined

所以实际项目里经常:

js 复制代码
const user = users.find(item => item.id === userId)

if (user) {
  console.log(user.name)
}

9.4 some:有没有至少一个符合条件

这个在业务判断里特别好用。

例如:

js 复制代码
const result = users.some(item => item.enabled)

意思:

有没有至少一个启用用户?

结果:

js 复制代码
true

因为张三、王五都是启用状态。


假设维修项目

例如:

js 复制代码
const parts = [
  {
    partName: '屏幕',
    issuedQty: 0
  },
  {
    partName: '电池',
    issuedQty: 1
  }
]

判断:

有没有备件已经领用了?

直接:

js 复制代码
const hasIssued = parts.some(item => item.issuedQty > 0)

结果:

js 复制代码
true

然后:

js 复制代码
if (hasIssued) {
  this.$message.warning('已有备件领用,不能取消工单')
  return
}

这就是一个非常典型的业务场景。


9.5 every:是不是全部符合条件

例如:

js 复制代码
const result = users.every(item => item.enabled)

意思:

是不是所有用户都启用了?

因为李四:

js 复制代码
enabled: false

所以:

js 复制代码
false

案例

例如维修方案有多个项目:

js 复制代码
const items = [
  {
    name: '换屏',
    confirmed: true
  },
  {
    name: '换电池',
    confirmed: true
  }
]

判断:

是不是所有项目都已经确认?

js 复制代码
const allConfirmed = items.every(item => item.confirmed)

结果:

js 复制代码
true

如果其中一个:

js 复制代码
confirmed: false

那么:

js 复制代码
allConfirmed === false

someevery 最容易混

可以直接这么记:

text 复制代码
some
=
有一个就行

every
=
必须全部满足

9.6 五个方法放一起看

还是:

js 复制代码
const users = [
  { id: 1, name: '张三', age: 18, enabled: true },
  { id: 2, name: '李四', age: 25, enabled: false },
  { id: 3, name: '王五', age: 30, enabled: true }
]

map

js 复制代码
users.map(item => item.name)

结果:

js 复制代码
['张三', '李四', '王五']

意思:

转换。


filter

js 复制代码
users.filter(item => item.age >= 20)

结果:

text 复制代码
李四、王五组成的新数组

意思:

筛选多条。


find

js 复制代码
users.find(item => item.id === 2)

结果:

text 复制代码
李四这个对象

意思:

找一条。


some

js 复制代码
users.some(item => item.enabled === false)

结果:

js 复制代码
true

意思:

有没有一个满足。


every

js 复制代码
users.every(item => item.age >= 18)

结果:

js 复制代码
true

意思:

是不是全部满足。


一个真实业务案例

假设接口返回维修备件:

js 复制代码
const parts = [
  {
    id: 1,
    name: '屏幕',
    quantity: 2,
    status: 'USED'
  },
  {
    id: 2,
    name: '电池',
    quantity: 1,
    status: 'RETURNED'
  },
  {
    id: 3,
    name: '摄像头',
    quantity: 1,
    status: 'USED'
  }
]

找到电池

js 复制代码
const battery = parts.find(item => item.name === '电池')

获取所有已使用备件

js 复制代码
const usedParts = parts.filter(item => item.status === 'USED')

获取备件名称

js 复制代码
const partNames = parts.map(item => item.name)

结果:

js 复制代码
['屏幕', '电池', '摄像头']

判断有没有退货

js 复制代码
const hasReturned = parts.some(item => item.status === 'RETURNED')

判断是否全部已使用

js 复制代码
const allUsed = parts.every(item => item.status === 'USED')

这种写法以后在前端进行状态判断、列表处理、接口数据转换时会大量使用。


顺便补一个 forEach

这个虽然不是 ES6 新增,但实战特别常见。

js 复制代码
users.forEach(item => {
  console.log(item.name)
})

它的目的通常就是:

遍历做事情。

map 最大区别是:

forEach

偏向:

text 复制代码
遍历执行

例如:

js 复制代码
users.forEach(item => {
  item.checked = false
})

map

偏向:

text 复制代码
处理后生成新的数组

例如:

js 复制代码
const names = users.map(item => item.name)

所以不要为了遍历而乱用 map

如果你根本不需要返回新数组:

js 复制代码
users.map(item => {
  console.log(item.name)
})

虽然能运行,但不推荐。

应该:

js 复制代码
users.forEach(item => {
  console.log(item.name)
})

第 7~9 个总结

现在可以记成:

text 复制代码
7. 剩余参数 ...args
   ↓
   收集函数参数

8. 默认参数
   ↓
   参数没传时使用默认值

9. 数组方法
   ↓
   map    转换
   filter 筛选多条
   find   找一条
   some   至少一个满足
   every  全部满足

尤其是第 9 个,我建议你把下面这一组直接记熟:

js 复制代码
list.map(item => ...)

把数据转换成新数组。

js 复制代码
list.filter(item => ...)

过滤数据。

js 复制代码
list.find(item => ...)

找到第一条。

js 复制代码
list.some(item => ...)

有没有符合条件的。

js 复制代码
list.every(item => ...)

是不是全部符合条件。

相关推荐
sunly_1 小时前
TypeScript总结:15、类型速查
前端·javascript·typescript
2601_953988071 小时前
Ricon组态系统vs传统组态软件:为什么选择新一代Web组态平台
前端·后端·物联网·tcp/ip·数学建模·前端框架
天空之城--1 小时前
Claude Code 高效开发 Web 2D/3D 完全指南:心法、自定义 Skill 体系与社区技能包实战
前端·3d
breeze jiang1 小时前
Next.js App Router 父子组件 RSC 拆分实战:从 Redis Hash 到客户端交互的最小化边界
javascript·redis·哈希算法
IT_陈寒1 小时前
SpringBoot自动配置坑了我三天,原来漏了这个注解
前端·人工智能·后端
丫头,冲鸭!!!1 小时前
记账网站-post功能
javascript·个人开发
鬼手点金1 小时前
Scrapy + Playwright 完整示例(JS 动态渲染网页)
开发语言·javascript·爬虫·python·scrapy·html·json
逝水无殇2 小时前
HTML 文本格式化详解:掌握 <strong>、<em>、<mark>、<del> 等常用标签
前端·javascript·html
特立独行的猫a2 小时前
DeepSeek Harness插件和工具的区别介绍及开发入门指南
前端·ai·agent·插件·deepseek·harness