... 属于 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 }) 中:

  1. ✅ 创建副本:避免共享引用
  2. ✅ 保持独立:修改不影响默认配置
  3. ✅ 响应式基础:为 Vue 响应式系统提供独立数据
  4. ✅ 安全操作:可以安全地修改而不担心副作用

这是 Vue 3 中创建响应式数据的推荐模式,确保数据的独立性和安全性。