... 属于 JavaScript/TypeScript 的展开语法(Spread Syntax)。
🎯 简单理解
... 就是”把对象拆开,再装到一个新对象里”。
💡 类比例子
现实生活类比
你有:一个盒子,里面有 {苹果, 香蕉, 橙子}
操作:...盒子
结果:得到一个新的盒子,里面有 {苹果, 香蕉, 橙子}代码对比
// 原始对象
const 旧盒子 = { 苹果: '🍎', 香蕉: '🍌', 橙子: '🍊' }
// 展开语法
const 新盒子 = { ...旧盒子 }
// 新盒子 = { 苹果: '🍎', 香蕉: '🍌', 橙子: '🍊' }
🔧 实际效果
浅拷贝对象
const original = { a: 1, b: 2, c: 3 }
const copy = { ...original }
console.log(copy) // { a: 1, b: 2, c: 3 }
console.log(original === copy) // false,是不同的对象
📊 与直接赋值的区别
| 方式 | 结果 | 是否共享引用 |
|---|---|---|
const a = b |
引用同一个对象 | ✅ 是 |
const a = { ...b } |
创建新对象 | ❌ 否 |
示例对比
const defaultConfig = { name: '默认', value: 0 }
// 方式1:直接赋值(共享引用)
const config1 = defaultConfig
config1.name = '修改了'
console.log(defaultConfig.name) // '修改了' ❌ 原对象被改了
// 方式2:展开语法(独立对象)
const config2 = { ...defaultConfig }
config2.name = '修改了'
console.log(defaultConfig.name) // '默认' ✅ 原对象不变
💡 在响应式数据中的应用
为什么需要 ...?
// ❌ 不好的:共享引用
const notificationConfig = ref<any>(initNotificationConfig)
// 如果修改 notificationConfig.value
// initNotificationConfig 也会被修改
// ✅ 好的:独立副本
const notificationConfig = ref<any>({ ...initNotificationConfig })
// 修改 notificationConfig.value
// 不会影响 initNotificationConfig
🔄 扩展功能
1. 合并对象
const defaults = { a: 1, b: 2 }
const overrides = { b: 3, c: 4 }
// 合并,后面的覆盖前面的
const merged = { ...defaults, ...overrides }
// { a: 1, b: 3, c: 4 }
2. 添加新属性
const base = { x: 10, y: 20 }
const extended = { ...base, z: 30 }
// { x: 10, y: 20, z: 30 }
3. 覆盖部分属性
const config = { ...initNotificationConfig, EMAIL: 'new@example.com' }
// 保持其他默认值,只修改 EMAIL
⚡ 性能考虑
浅拷贝 vs 深拷贝 ★★★
例1:
// 展开语法是浅拷贝
const obj = {
a: 1,
b: { nested: 2 } // 嵌套对象
}
const copy = { ...obj }
copy.a = 999 // ✅ 不影响原对象
copy.b.nested = 888 // ❌ 会影响原对象,因为 嵌套对象是引用 ★
例2:
// 如果 initSofToolConfig 有嵌套对象
const initSofToolConfig = {
simple: 'value',
nested: { a: 1, b: 2 } // 嵌套对象
}
// 需要深度拷贝
const safeCopy = {
...initSofToolConfig,
nested: { ...initSofToolConfig.nested } // 手动展开嵌套 ★★
}🎯 一句话总结
{ ...initSoftoolCNConfig } 创建 initSoftoolCNConfig 的 浅拷贝 副本,确保新对象独立,修改不会影响原对象。
💡 记忆技巧
| 符号 | 意思 | 类比 |
|---|---|---|
...obj |
把对象”展开” | 把盒子里东西倒出来 |
{ ...obj } |
装到新对象里 | 装到新盒子里 |
| 作用 | 创建独立副本 | 复制一份,各改各的 |
📋 总结
在 const softoolcnConfig = ref<any>({ ...initSoftoolCNConfig }) 中:
- ✅ 创建副本:避免共享引用
- ✅ 保持独立:修改不影响默认配置
- ✅ 响应式基础:为 Vue 响应式系统提供独立数据
- ✅ 安全操作:可以安全地修改而不担心副作用
这是 Vue 3 中创建响应式数据的推荐模式,确保数据的独立性和安全性。
