视频加载失败

ES6展开运算符

1170 字
6 分钟
ES6展开运算符

数组展开运算符的基本用法#

数组展开运算符是 ES6 的 ... 语法,用来把“数组拆开成单个元素”。

基本语法

const arr = [1, 2, 3];
console.log(...arr);
//等价于
console.log(1, 2, 3);

区分剩余参数和展开运算符#

与剩余参数的区别:剩余参数是把多个值收集成数组,展开运算符是把数组拆成多个值;同一个符号,不同位置决定含义

写法位置作用
...args函数参数收集剩余参数
...arr调用/表达式展开数组

例子:

//剩余参数
const add = (...args) => {
console.log(...args); //扩展运算符
};
add(1, 2, 3);
console.log([...[1, 2, 3], 4]); //扩展运算符[ 1, 2, 3, 4 ]

数组展开运算符的应用#

例子:

//数组合并
const a = [1, 2];
const b = [3, 4];
const c = [...a, ...b];
console.log(c); // [1, 2, 3, 4]
//数组拷贝(浅拷贝)
const arr1 = [1, 2, 3];
const arr2 = [...arr1];
console.log(arr2); // [1, 2, 3]
//函数传参展开
function sum(a, b, c) {
return a + b + c;
}
const nums = [1, 2, 3];
console.log(sum(...nums)); // 6
//找最大/最小值
const nums = [5, 2, 9];
console.log(Math.max(...nums)); // 9
//字符串转数组
const str = "abc";
console.log([...str]); // ['a', 'b', 'c']
//类数组转数组
function fn() {
const arr = [...arguments];
console.log(arr);
}
fn(1, 2, 3);
//nodelist也是类数组
const nodes = document.querySelectorAll("div");
const arr = [...nodes];
console.log(arr);

对象展开运算符的基本用法#

展开对象

const obj = { a: 1, b: 2 };
console.log({...arr} === obj);

合并对象

const obj1 = {
name: "Tom"
};
const obj2 = {
age: 18////如果属性相同,会覆盖前面对象的属性
};
const result = {
...obj1,
...obj2
};
console.log(result);
// { name: 'Tom', age: 18 }

对象展开的疑惑

“展开(spread)”这个名字容易让人误以为:

const obj = { a: 1, b: 2 };
...obj
//会变成
a: 1, b: 2

然后单独存在。实际上 对象展开只能出现在另一个对象字面量中,它的作用是:将源对象的可枚举属性复制到当前对象中。

const obj = { a: 1, b: 2 };
const newObj = {
...obj
};
//JavaScript 引擎实际上会理解成类似:
const newObj = {
a: 1,
b: 2
};

这里确实发生了“展开”,但展开后的结果必须放进一个新的对象里。

为什么数组看起来更像“展开”?

const arr = [1, 2, 3];
console.log(...arr);//1 2 3

因为数组的展开运算符会把元素变成多个独立值,所以数组的“展开感”特别强。

对象为什么不能这样?假设允许:

console.log(...obj);
console.log(a:1, b:2) // 这根本不是合法JS

对象本身不是一个值序列,而是一组 key-value 映射。因此对象展开只能出现在需要属性列表的地方

{
...obj
}

因此对象展开运算符的本质不是:把对象拆开;而是:把对象的属性复制到当前位置的对象中

所以很多开发者更愿意把对象展开理解成:

Object.assign({}, obj)

的语法糖,而不是像数组那样真正意义上的“展开成多个值”。这样理解会更准确。

对象展开运算符的注意事项#

空对象的展开

console.log({ ...{} });//{}

非对象展开

如果不是对象,会转其对象,然后将属性展开

console.log({ ...1 });
//等价于
console.log(new Object(1));
//console.log({ ...new Object(1) });
console.log({ ...'hello' }); //特殊,类数组:{ '0': 'h', '1': 'e', '2': 'l', '3': 'l', '4': 'o' }
console.log({ ...[1, 2, 3] });//在对象中展开数组类数组:{ '0': 1, '1': 2, '2': 3 }

对象中的对象属性展开

不会展开对象中的对象属性

const user = {
name: 'Tom',
address: {
city: 'Beijing',
street: 'xxx',
},
};
const user1 = {
name: 'Alex',
address: {
city1: 'Shenzheng',
street1: 'xxx',
},
};
console.log({ ...user });
console.log({ ...user, ...user1 }); //addr没有展开所以覆盖了{ name: 'Alex', address: { city1: 'Shenzheng', street1: 'xxx' } }
//正常的合并对象只有属性名相同才会覆盖否则不会
const address = {
city: 'Beijing',
street: 'xxx',
};
const address1 = {
city1: 'Beijing',
street1: 'xxx',
};
console.log({ ...address, ...address1 }); //{ city: 'Beijing', street: 'xxx', city1: 'Beijing', street1: 'xxx' }

对象展开运算符的应用#

//使用展开运算符设置默认配置
function createUser(options = {}) {
const config = {
name: 'Guest',
age: 18,
...options
};
return config;
}
createUser({
name: 'Tom'
});
//删除属性(结合解构)
const user = {
name: 'Tom',
age: 18,
password: '123456',
};
const { password, ...safeUser } = user;
console.log(password, safeUser); //123456 { name: 'Tom', age: 18 }
//展开嵌套对象属性
const user = {
name: 'Tom',
address: {
city: 'Beijing',
street: 'xxx'
}
};
const result = {
...user,
...user.address
};
//条件添加属性
const isAdmin = true;
const user = {
name: 'Tom',
...(isAdmin && {
role: 'admin'
})
};
//更新对象属性
const user = {
name: 'Tom',
age: 18
};
const updatedUser = {
...user,
age: 20
};

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

ES6展开运算符
https://f.youzi177.cn/posts/2026102107es6-zhan-kai-yun-suan-fu/
作者
小封鸭
发布于
2026-10-21
许可协议
CC BY-NC-SA 4.0

评论区

Profile Image of the Author
小封鸭
小楼一夜听春雨,深巷明朝卖杏花
公告
欢迎来到我的博客。这里主要记录前端全栈和日常内容
分类
标签
最新动态
站点统计
文章
60
分类
3
标签
12
总字数
107,734
运行时长
0 天
最后活动
0 天前
站点信息
构建平台
EdgeOne Pages
博客版本
Firefly v6.16.8
文章许可
CC BY-NC-SA 4.0
文章目录