展开运算符与嵌套结构
展开运算符和嵌套结构是操作复杂数据的两个核心工具。
展开运算符
数组展开
JavaScript
const arr1 = [1, 2];
const arr2 = [3, 4];
const merged = [...arr1, ...arr2]; // [1, 2, 3, 4]
const withInsert = [0, ...arr1, 5]; // [0, 1, 2, 5]
复制数组
JavaScript
const original = [1, 2, 3];
const copy = [...original];
copy[0] = 99;
console.log(original); // [1, 2, 3](不受影响)
展开运算符执行的是浅拷贝,嵌套对象/数组仍共享引用。
函数参数展开
JavaScript
const nums = [3, 1, 4, 1, 5];
Math.max(...nums); // 5
Math.min(...nums); // 1
console.log(...nums); // 3 1 4 1 5
对象展开
JavaScript
const base = { name: 'Tom', age: 25 };
const extended = { ...base, city: 'Beijing' };
// { name: 'Tom', age: 25, city: 'Beijing' }
合并对象与覆盖
JavaScript
const defaults = { theme: 'light', lang: 'zh' };
const userSettings = { theme: 'dark' };
const config = { ...defaults, ...userSettings };
// { theme: 'dark', lang: 'zh' }(后者覆盖前者)
字符串展开
JavaScript
const chars = [...'hello']; // ['h', 'e', 'l', 'l', 'o']
对象与数组嵌套
数组嵌套
JavaScript
const matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
];
console.log(matrix[1][2]); // 6
对象嵌套
JavaScript
const company = {
name: 'TechCo',
address: {
city: 'Beijing',
district: 'Haidian',
location: {
lat: 39.9,
lng: 116.4
}
},
departments: ['Engineering', 'Design', 'Marketing']
};
console.log(company.address.location.lat); // 39.9
console.log(company.departments[0]); // 'Engineering'
嵌套数据遍历
JavaScript
const users = [
{ name: 'Tom', skills: ['JS', 'React'] },
{ name: 'Jerry', skills: ['Python', 'Django'] }
];
const allSkills = users.flatMap(u => u.skills);
// ['JS', 'React', 'Python', 'Django']
users.forEach(user => {
console.log(user.name);
user.skills.forEach(skill => {
console.log(' -', skill);
});
});
嵌套数据修改(不可变方式)
JavaScript
const state = {
user: {
name: 'Tom',
profile: {
age: 25,
city: 'Beijing'
}
}
};
const newState = {
...state,
user: {
...state.user,
profile: {
...state.user.profile,
age: 26
}
}
};
console.log(newState.user.profile.age); // 26
console.log(state.user.profile.age); // 25(原数据不变)
浅拷贝 vs 深拷贝
JavaScript
const original = {
name: 'Tom',
address: { city: 'Beijing' }
};
// 浅拷贝
const shallow = { ...original };
shallow.address.city = 'Shanghai';
console.log(original.address.city); // 'Shanghai'(被影响!)
// 深拷贝
const deep = JSON.parse(JSON.stringify(original));
deep.address.city = 'Shenzhen';
console.log(original.address.city); // 'Beijing'
// 现代深拷贝
const deep2 = structuredClone(original);
实际应用
Rest 参数
JavaScript
function sum(...nums) {
return nums.reduce((acc, cur) => acc + cur, 0);
}
sum(1, 2, 3, 4); // 10
function greet(greeting, ...names) {
return `${greeting}, ${names.join(' and ')}`;
}
greet('Hi', 'Tom', 'Jerry'); // 'Hi, Tom and Jerry'
条件属性
JavaScript
const isActive = true;
const user = {
name: 'Tom',
...(isActive && { status: 'online' })
};
// { name: 'Tom', status: 'online' }
要点总结
...展开数组/对象得到的是浅拷贝,嵌套引用仍共享- 对象展开同名属性时,后者覆盖前者
- 嵌套数据修改需逐层展开,保持不可变性
structuredClone是推荐的深拷贝方式- Rest 参数
...args收集剩余参数为数组