JS中的 解构、可扩展运算符(...)

一、解构([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的值为准。

posted on   itjeff  阅读(189)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示