惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
爱范儿
爱范儿
宝玉的分享
宝玉的分享
Apple Machine Learning Research
Apple Machine Learning Research
博客园 - Franky
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 三生石上(FineUI控件)
人人都是产品经理
人人都是产品经理
阮一峰的网络日志
阮一峰的网络日志
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Last Week in AI
Last Week in AI
博客园 - 聂微东
大猫的无限游戏
大猫的无限游戏
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
罗磊的独立博客
博客园 - 叶小钗
WordPress大学
WordPress大学
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
酷 壳 – CoolShell
酷 壳 – CoolShell
小众软件
小众软件
博客园 - 司徒正美
博客园 - 【当耐特】
IT之家
IT之家

博客园 - itjeff

sql server中展示数据库所有表结构的查询语句,然后可以做Excel导出 jQuery的.each()方法中return的坑 the server responded with a status of 413 (Request Entity Too Large) 解决 js 常用函数 push()、pop()、shift()、unshift()、slice()、splice() 等 Win10 HEU KMS Activator被识别为病毒怎么办? 解决equal to 运算中 "Chinese_PRC_CI_AS" 和 "Chinese_PRC_CS_AS" 之间的排序规则冲突 sql server 数据库设置不区分大小写的设置 bootstraptable 列隐藏 sql server 2014 新建授权某个表的用户 list和datatable相互转化 C#的小数位保留以及四舍五入 Windows 服务器远程桌面授权120天到期 sql server 清空日志操作步骤 查看SQL Server数据库各表数据量与占用空间 SQL Server 日志文件收缩 一文说清楚http、tcp、socket、websocket区别 Access-Control-Allow- 设置 跨域资源共享 CORS 详解 Bootstrap 模态框(Modal)插件的基本应用 js 中的相对路径的写法
JS中的 解构、可扩展运算符(...)
itjeff · 2024-09-13 · via 博客园 - itjeff

一、解构([x, x, x] =[1, 2, 3])

解构,英文名叫Destructuring。核心就是 [A, B, C] = [1, 2, 3]这种形式。其核心思想就是把数组/对象的每个元素解构出来。虽然这话说的很抽象,但举个例子你就明白了。

1.1 数组解构

const [a, b, c] = [1, 2, 3]
console.log(a) //1
console.log(b) //2
console.log(c) //3

结构核心思路

如上图所示,结构基本核心思路就是这样,相当简单,1解构给a,2解构给b,3解构给c。

对于嵌套数组,解构方法也是也是一样的,我个人比较喜欢这样写:

const arr = [1, 2, 3, [4, 5]]
      const [a, b, c, [d, e]] = arr //为了方便理解,我在这行代码前面多打了几个空格

1.2 对象

对象也差不多的啦,比如说:

const obj = {
    "userId": 1,
    "id": 1,
    "title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
    "body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
  }
const {userId, id, title, body} = obj

对象解构和数组解构唯一的区别在于,对象要保证key的名称是相同的才能解构,如果名称不同,则解构不成功。另外解构出来的key命名你不喜欢,你可以reName。比如:

const {userId, id, title, body:textBody} = obj
console.log(textBody)

对于嵌套对象,只需要解构出来重复刚刚的解构过程即可,比如说:

const obj = {
   a:1,
   b:2,
   c:{
    d:3,
    e:4
  }
}
// 方法1:
const {a, b, {d, e}} = obj

// 方法2:(个人喜欢这种,嵌套对象的方法1这种写法看着很让人疑惑)
const {a, b, c} = obj
const {d, e} = c //对c这个对象再进行一步解构

二、Spread and rest Operator(...)

中文似乎叫可扩展运算符,但我特意标题写英文是因为英文好理解一些。特征就是三个点...

其实我特意写上面的英文是因为,这个ES6的语法是包括两部分的,也就是Spread和rest

2.1 rest(收拢)

rest语法允许我们将一个不定数量的参数表示为一个数组。

这是MDN的语录,划分一下主谓宾,一般来说就是将多个参数拼成数组(多个参数 => 数组),但如果你对对象{}使用,则是收拢成对象。啥意思呢,举个例子:

function sum(multiplier, ...numbers){
     console.log(numbers) // [4, 2]
     return  multiplier * numbers.reduce((sum ,number) => sum + number, 0)
}

sum(10, 4, 2) //60 因为10* (4+2)


const obj = { a:1, b:2, c:3, d:{e:4} }
const {a, b, ...rest} = obj // 意思是a, b解构出来,obj剩余参数则收拢在一起
//只不过此时收拢后的结果不是数组,而是收拢在一起成为对象
console.log(rest) //{c:3, d:{e:4}}

如上面代码所示,打印numbers时,是一个数组[4, 2],正如上面MDN所定义的,rest语法让我们将多个参数合并成一个数组。参数10时属于multiplier的,剩余参数4,2自然就被...numbers拼成了数组。

2.2 Spread(展开)

相比于rest,聚拢在一起,Spread则是展开,比如:

const names = ["Kyle", "Cook"]
function concatName(firstName, lastName){ 
    console.log(firstName + "" + lastName)
}

concatName(...names) // Kyle Cook

2.3 小结

rest Operator则是把多个参数收拢,Spread则是把聚在一起的元素展开。

收拢:则是把元素收拢在一起,变成一个数组。

展开:则是把数组/对象展开,拿到里面的每个元素。

在使用...时,注意自己用的是spread还是rest,比如说有个变量numbers,你 ...numbers,你应该想想自己用的是展开(rest),还是收拢(spread)

2.4 拷贝

...最有用的就是拷贝一份全新的数组/对象,比如说:

const arr = [1, 2, 3]
const newArr = [...arr] //把arr展开,然后再用[]创建一个新数组,最后把创建出来的数组赋值给newArr

// 简化模型理解就是:
// const newArr = [arr[0], arr[1], arr[2]] 就是这么个意思

另外我想提及的一点就是,拷贝其实跟赋值完全不是一个概念,拷贝会开辟一个新地址,啥意思呢?比如说:

1>这是拷贝的:

const arr = [1, 2, 3]
const newArr = [...arr]
newArr.push(100)

console.log(arr) // [1, 2, 3]
console.log(newArr) // [1, 2, 3, 100]

2>这是赋值:

const arr = [1, 2, 3]
const newArr = arr
newArr.push(100)

console.log(arr) // [1, 2, 3, 100]
console.log(newArr) // [1, 2, 3, 100]

我有一篇文章介绍过赋值的情况lzb123:Reference vs Value,简单来说,就是拷贝时,arr地址是0x01,newArr地址是0x02。但赋值时arr和newArr地址都是0x01。因为赋值时你把arr地址赋值给了newArr。所以它两共用一个地址。

2.5 拷贝注意事项

就是如果拷贝时,后面的有一个key跟前面的一样,则以排在后面的key的值为准,请让我举个例子解释一下:

const obj = {a: 1, b: 2, c: 3}
const newObj = {...obj, c: 4} //拷贝时,后面的key(指的是c)和前面展开obj时出现的c这个key是一样的
//所以以后面的c的值为准
console.log(newObj)  //{a: 1, b: 2, c: 4}

//哪个c在后面以哪个为准
const newObj2 = {c:4, ...obj}
console.log(newObj2) //{a: 1, b: 2, c: 3} 此时,以后面那个c,也就是obj展开后的c:3为准

简单来说,拷贝时,碰到一样的key,哪个key排在后面,以哪个key的值为准。