深入理解 JavaScript/TypeScript 中的展开运算符(...)

在 JavaScript 和 TypeScript 中,... 运算符(称为展开运算符,英文 Spread Operator)是一个非常强大且常用的语法。它可以让代码更简洁、更灵活,适用于数组、对象、函数参数等多种场景。本文将详细介绍它的用法,并通过示例帮助你彻底掌握它。


1. 什么是展开运算符(...)?

展开运算符 ... 允许将一个可迭代对象(如数组、字符串、Set、Map 等)“展开”成独立的元素。它的核心作用是解构数据,让代码更简洁。

基本语法

const newArray = [...iterable]; // 展开数组
const newObj = { ...object };   // 展开对象
func(...args);                  // 展开函数参数

2. 展开运算符的常见用法

(1)数组展开

① 合并数组
const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
const merged = [...arr1, ...arr2]; // [1, 2, 3, 4, 5, 6]
② 复制数组(浅拷贝)
const original = [1, 2, 3];
const copy = [...original]; // [1, 2, 3]
③ 在 push 中使用
const array1 = [1, 2];
const array2 = [3, 4];
array1.push(...array2); // array1 变为 [1, 2, 3, 4]
④ 替代 apply 方法
// 旧方法:使用 apply
Math.max.apply(null, [1, 2, 3]); // 3

// 新方法:使用展开运算符
Math.max(...[1, 2, 3]); // 3

(2)对象展开

① 合并对象
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const mergedObj = { ...obj1, ...obj2 }; // { a: 1, b: 2, c: 3, d: 4 }
② 复制对象(浅拷贝)
const original = { a: 1, b: 2 };
const copy = { ...original }; // { a: 1, b: 2 }
③ 覆盖属性
const user = { name: "Alice", age: 25 };
const updatedUser = { ...user, age: 26 }; // { name: "Alice", age: 26 }

(3)函数参数展开

① 可变参数(Rest Parameters)
function sum(...numbers: number[]) {
  return numbers.reduce((acc, num) => acc + num, 0);
}
sum(1, 2, 3); // 6
② 传递数组参数
function greet(name: string, age: number) {
  return `Hello, ${name}! You are ${age} years old.`;
}
const args = ["Alice", 25] as const;
greet(...args); // "Hello, Alice! You are 25 years old."

3. 展开运算符 vs. 剩余参数(Rest Parameters)

虽然 ... 既可以用于展开spread),也可以用于收集剩余参数rest),但它们的用途不同:

场景 示例 作用
展开 [...arr] 或 { ...obj } 将数组或对象展开
剩余参数 function(...args) 收集剩余参数为数组

剩余参数示例

function logNames(first: string, ...rest: string[]) {
  console.log(`First: ${first}, Others: ${rest.join(", ")}`);
}
logNames("Alice", "Bob", "Charlie"); // "First: Alice, Others: Bob, Charlie"

4. 注意事项

  1. 浅拷贝问题
    ... 只能进行浅拷贝,如果对象或数组包含嵌套引用,修改嵌套数据会影响原数据。

    const original = [{ a: 1 }];
    const copy = [...original];
    copy[0].a = 2; // original[0].a 也会变成 2
  2. 仅适用于可迭代对象
    ... 不能直接用于普通对象(除非是 ES6+ 环境支持的对象展开)。

  3. TypeScript 类型推断
    在 TypeScript 中,展开运算符能正确推断类型,但有时可能需要 as const 或显式类型声明。


5. 总结

用途 示例
数组展开 [...arr1, ...arr2]
对象展开 { ...obj1, ...obj2 }
函数参数展开 func(...args)
剩余参数 function(...args)

展开运算符 ... 让 JavaScript/TypeScript 代码更简洁、更灵活,适用于数组操作、对象合并、函数参数传递等多种场景。掌握它,能让你的开发效率大幅提升!

你可能感兴趣的:(TypeScript,JavaScript,javascript,typescript,开发语言)