一篇文章帮你彻底搞懂扩展运算符

什么是扩展运算符号?

扩展运算符是一种操作符,它可以将我们可迭代对象扩展为单独的元素。常用于在函数调用、数组构造、构造字面量对象等情况下,将数组、类数组对象或字符串展开为单独的元素,或将对象展开为键值对。在语法层面展开数据

扩展运算符特性

  • 扩展运算符允许在其后接受表达式。
  • 在数组或函数参数中使用展开语法(...)时,该语法只能用来将可迭代对象(即部署了 Iterator 遍历器接口的对象)的数组表达式或字符串在语法层面进行展开操作。
  • 扩展运算符可用于展开/合并数组,将类数组对象转换为数组,并且可以用于接收参数。
  • 扩展运算符仅执行浅拷贝,这意味着它只会复制对象的引用,而不是对象本身的内容。
  • 在使用扩展运算符时,需要记住扩展运算符并不会克隆相同的属性

结合代码进行说明

扩展运算符允许在其后接受表达式

js 复制代码
// 设定变量 x 的值为 10
const x = 10;

// 构造数组 arr
const arr = [
  // 判断 x 是否大于 0,如果是则返回包含 'a' 的数组,否则返回空数组,然后使用扩展运算符将其展开
  ...(x > 0 ? ['a'] : []),
  // 将 'b' 加入数组 arr
  'b',
];

// 构造对象 obj
const obj = {
  // 判断 x 是否大于 1,如果是则返回包含属性 'a' 的对象,否则返回空对象,然后使用扩展运算符将其展开
  ...(x > 1 ? { a: 1 } : {}),
  // 添加属性 'b',值为 2
  b: 2,
};

// 输出数组 arr
console.log(arr); // ["a", "b"]

// 输出对象 obj
console.log(obj); // { a: 1, b: 2 }

扩展运算符可用于展开/合并数组,将类数组对象转换为数组,并且可以用于接收参数。

使用运算符展开数组
js 复制代码
const array1 = [1, 2, 3];
const array2 = [4, 5, ...array1, 6];

console.log(array2); // 输出:[4, 5, 1, 2, 3, 6]
使用运算符合并数组

示例一

js 复制代码
const coffee = ['coffee', 'water'];
const spices = ['cinnamon', 'nutmeg', 'cardamom'];

const coffeeReady = [...coffee, ...spices];

console.log(coffeeReady) 
// 输出:['coffee', 'water', 'cinnamon', 'nutmeg', 'cardamom'];

示例二

js 复制代码
const mySiblings = { 
  brothersName: 'Philip', 
  sistersName: 'Lara' 
};

const myFamily = { 
  fathersName: 'Michael', 
  mothersName: 'Louise',
  ...mySiblings
};
// Now we can treat brothersName and sistersName as 
// a property of myFamily:
console.log(myFamily.brothersName) 
将类数组对象转换为数组
js 复制代码
// 类数组对象
const arrayLikeObject = { 0: 'a', 1: 'b', 2: 'c', length: 3 };

// 将类数组对象转换为数组
const array = [...arrayLikeObject];

console.log(array); // 输出:['a', 'b', 'c']

将字符串转换成数组

js 复制代码
const str = 'coffee';
const letters = [...str, 's.', '☕️']; 
console.log(letters);// ["c", "o", "f", "f", "e", "e", "s.", "☕️"]
使用运算符接收参数
js 复制代码
function myFunction(x, y, z) {
  console.log(x, y, z);
}

const args = [1, 2, 3];
myFunction(...args); // 输出:1 2 3

扩展运算符并不会克隆相同的属性

在下面的例子中,我们的vegetable1对象和vegetable2对象里都有一个相同的属性potato,但是跳转的值不同,在使用扩展运算符时,它并不会克隆相同的属性,而是会将后面对象中的属性值覆盖前面对象中的属性值。

js 复制代码
const vegetable1 = { 
  potato: '土豆', 
  tomato: '番茄',
  cucumber: '青瓜'
};
const vegetable2 = { 
  potato: '马铃薯', 
  cucumber: '黄瓜', 
  pumpkin: '南瓜', 
};

const allVegetable = { ...vegetable1, ...vegetable2 };
console.log(allVegetable);
/* 输出
{ 
  tomato: '番茄',
  cucumber: '青瓜'
  potato: '马铃薯', 
  cucumber: '黄瓜', 
  pumpkin: '南瓜', 
}
*/

扩展运算符仅执行浅拷贝

js 复制代码
let a = [1, [2, 3]]; // 定义数组 a,其中包含一个嵌套的数组 [2, 3]
const b = [4, 5, 6];

let c = [...a, ...b]; // 将数组 a 和数组 b 展开,并将它们的元素合并到数组 c 中
console.log(c);
// 输出: [1, [2, 3], 4, 5, 6]

a[0] = 11; // 修改数组 a 的第一个元素为 11
a[1][0] = 22; // 修改数组 a 中嵌套数组的第一个元素为 22

console.log(c);
// 输出: [1, [22, 3], 4, 5, 6]
  • 在上面的代码中,当我们使用扩展运算符 ... 将数组 a 和数组 b 展开到数组 c 中时,c 中的 [2, 3] 实际上是对数组 a 中嵌套数组的引用。因此,c 中的第二个元素 [2, 3] 并不是复制了数组 a 中的 [2, 3],而是引用了相同的嵌套数组。
  • 当我们修改数组 a 中的元素时,由于 c 中的嵌套数组和数组 a 中的嵌套数组是同一个引用,所以 c 中的嵌套数组也会被修改。
  • 因此,尽管我们只修改了数组 a,但数组 c 也受到了影响,其中嵌套数组的元素被修改为了 [22, 3]

注意:浅拷贝只能复制对象或数组的顶层结构。如果原始对象或数组中包含嵌套的对象或数组,浅拷贝后的对象或数组仍然会与原始对象或数组共享相同的嵌套对象或数组。这意味着在浅拷贝中修改嵌套对象或数组会影响到所有相关的对象或数组。

讲到这里肯定很多人会一想到,Object.assign(),它同样也能将另一个对象里的值拷贝到目标对象中,那他们之间有什么区别呢?

Object.assign() 和扩展运算的区别
特性 扩展运算符 (...) Object.assign()
语法 更简洁,直观 语法稍微复杂,接受目标对象和一个或多个源对象作为参数
返回值 返回一个新的对象或数组,其中包含了源对象或数组的属性或元素 返回目标对象本身,并且修改后的对象会直接反映在目标对象上
用途 用于对象和数组的浅拷贝,以及数组的合并 用于将一个或多个源对象的属性复制到目标对象中,也可以用于对象的浅拷贝和属性的合并
处理非对象类型 仅能处理对象和数组 能处理非对象类型的值,如字符串、数字、布尔值等,并将它们包装成对象
属性的设置方式 忽略源对象中的非自身可枚举属性 复制所有可枚举属性,包括原型链上的属性
相关推荐
Swift社区1 小时前
在 Swift 中实现字符串分割问题:以字典中的单词构造句子
开发语言·ios·swift
new出一个对象1 小时前
uniapp接入BMapGL百度地图
javascript·百度·uni-app
没头脑的ht1 小时前
Swift内存访问冲突
开发语言·ios·swift
没头脑的ht1 小时前
Swift闭包的本质
开发语言·ios·swift
wjs20241 小时前
Swift 数组
开发语言
你挚爱的强哥2 小时前
✅✅✅【Vue.js】sd.js基于jQuery Ajax最新原生完整版for凯哥API版本
javascript·vue.js·jquery
stm 学习ing2 小时前
FPGA 第十讲 避免latch的产生
c语言·开发语言·单片机·嵌入式硬件·fpga开发·fpga
y先森3 小时前
CSS3中的伸缩盒模型(弹性盒子、弹性布局)之伸缩容器、伸缩项目、主轴方向、主轴换行方式、复合属性flex-flow
前端·css·css3
前端Hardy3 小时前
纯HTML&CSS实现3D旋转地球
前端·javascript·css·3d·html
susu10830189113 小时前
vue3中父div设置display flex,2个子div重叠
前端·javascript·vue.js