rest参数
Rest 参数(Rest Parameters)是 ES6 引入的一个非常实用的特性。它允许函数接受不定数量的参数,并将这些参数作为一个数组存储,从而简化了处理可变参数的代码。
Rest 参数语法
Rest 参数使用 … 语法,紧跟着参数名。它会将传递给函数的所有剩余参数收集成一个数组。
function sum(...numbers) {return numbers.reduce((total, num) => total + num, 0);
}console.log(sum(1, 2, 3)); // 输出:6
console.log(sum(10, 20, 30, 40)); // 输出:100
在这个例子中,…numbers 捕获所有传递给 sum 函数的参数,并将它们作为数组 numbers 处理。
Rest 参数的特点
只能是最后一个参数
Rest 参数必须是函数参数列表中的最后一个参数。如果在其他参数后使用 …,会抛出语法错误。
// 正确
function greet(message, ...names) {console.log(message);console.log(names);
}// 错误
function greet(...names, message) { // 报错console.log(names);console.log(message);
}
能够接收任意数量的参数
Rest 参数允许函数接收任意数量的传递参数,并将它们收集到一个数组中。即使没有传递任何参数,Rest 参数仍然是一个空数组。
function logMessages(...messages) {console.log(messages); // 输出参数数组
}logMessages("Hello", "World"); // 输出:["Hello", "World"]
logMessages(); // 输出:[]
与普通参数一起使用
Rest 参数可以与普通的命名参数一起使用,但它必须位于参数列表的最后。
function displayInfo(name, age, ...hobbies) {console.log(`Name: ${name}`);console.log(`Age: ${age}`);console.log(`Hobbies: ${hobbies.join(", ")}`);
}displayInfo("Alice", 30, "Reading", "Hiking", "Cooking");
// 输出:
// Name: Alice
// Age: 30
// Hobbies: Reading, Hiking, Cooking
Rest 参数与 arguments 对象的区别
arguments 对象是一个类数组对象,表示传递给函数的所有参数。然而,arguments 对象不是真正的数组,不能直接使用数组的方法(如 forEach、map、filter)。此外,arguments 是一个在所有函数中都存在的对象,并不支持解构。
与此不同,Rest 参数是一个真正的数组,可以直接使用数组的方法。
function test() {console.log(arguments); // 类数组对象console.log(Array.isArray(arguments)); // 输出:false
}function testRest(...args) {console.log(args); // 数组console.log(Array.isArray(args)); // 输出:true
}test(1, 2, 3);
testRest(1, 2, 3);
Rest 参数与解构结合
你还可以将 Rest 参数与解构语法结合使用,从而灵活地提取函数参数。
function splitData(first, second, ...rest) {console.log(first); // 输出:1console.log(second); // 输出:2console.log(rest); // 输出:[3, 4, 5, 6]
}splitData(1, 2, 3, 4, 5, 6);
结论
Rest 参数是一个非常强大的特性,能够使函数更灵活,支持处理不定数量的参数。它比 arguments 对象更易用,因为它是一个真正的数组,并且可以结合解构语法进行更灵活的处理。使用 Rest 参数,你可以避免处理大量的条件判断,使代码更加简洁和易读。
扩展运算符
扩展运算符(Spread Operator)是 ES6 引入的一种语法,它使用 … 表示符,可以展开数组或对象的元素。它与 Rest 参数(…)看起来相似,但用途和语境有所不同。
扩展运算符的基本语法
扩展运算符用于将一个数组或对象的元素“展开”成单个值,可以更简洁地进行合并、克隆等操作。
// 数组的扩展
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];console.log(arr2); // 输出:[1, 2, 3, 4, 5]// 对象的扩展
const obj1 = { name: "Alice", age: 25 };
const obj2 = { ...obj1, city: "New York" };console.log(obj2); // 输出:{ name: "Alice", age: 25, city: "New York" }
数组的扩展运算符
扩展运算符可以将数组展开为单个元素,常见的用途包括合并数组和克隆数组。
合并数组
你可以使用扩展运算符将多个数组合并成一个新的数组。
const arr1 = [1, 2];
const arr2 = [3, 4];
const combinedArr = [...arr1, ...arr2];console.log(combinedArr); // 输出:[1, 2, 3, 4]
克隆数组
使用扩展运算符可以快速克隆一个数组。它会展开原数组的所有元素,生成一个新数组。
const arr1 = [1, 2, 3];
const arr2 = [...arr1];console.log(arr2); // 输出:[1, 2, 3]
arr1[0] = 100;
console.log(arr1); // 输出:[100, 2, 3]
console.log(arr2); // 输出:[1, 2, 3] (原数组未改变)
传递数组元素作为函数参数
你可以使用扩展运算符将数组的元素传递给函数参数。
const arr = [1, 2, 3];
function sum(a, b, c) {return a + b + c;
}
console.log(sum(...arr)); // 输出:6
对象的扩展运算符
扩展运算符也可以用于对象,它用于浅拷贝对象或合并多个对象。
克隆对象
扩展运算符可以创建一个对象的浅拷贝,复制对象的所有可枚举属性。
const obj1 = { name: "Alice", age: 25 };
const obj2 = { ...obj1 };console.log(obj2); // 输出:{ name: "Alice", age: 25 }
obj1.age = 26;
console.log(obj1); // 输出:{ name: "Alice", age: 26 }
console.log(obj2); // 输出:{ name: "Alice", age: 25 } (浅拷贝,原对象不受影响)
合并对象
多个对象可以使用扩展运算符合并成一个新对象。如果多个对象有相同的键,后面的对象的值会覆盖前面的。
const obj1 = { name: "Alice" };
const obj2 = { age: 25 };
const obj3 = { city: "New York" };const mergedObj = { ...obj1, ...obj2, ...obj3 };
console.log(mergedObj); // 输出:{ name: "Alice", age: 25, city: "New York" }
如果键重复,后面的对象会覆盖前面的对象中的同名属性:
const obj1 = { name: "Alice", age: 25 };
const obj2 = { age: 26, city: "New York" };const mergedObj = { ...obj1, ...obj2 };
console.log(mergedObj); // 输出:{ name: "Alice", age: 26, city: "New York" }
合并数组对象
扩展运算符不仅可以用于合并简单对象,也可以用于合并数组中对象的属性。
const obj1 = { a: 1, b: 2 };
const obj2 = { b: 3, c: 4 };
const obj3 = { ...obj1, ...obj2 };console.log(obj3); // 输出:{ a: 1, b: 3, c: 4 }
扩展运算符与 concat 的比较
扩展运算符和 concat 方法都可以用来合并数组,但它们有不同的使用方式和行为:
const arr1 = [1, 2];
const arr2 = [3, 4];// 使用 concat 合并
const combinedArr1 = arr1.concat(arr2);
console.log(combinedArr1); // 输出:[1, 2, 3, 4]// 使用扩展运算符合并
const combinedArr2 = [...arr1, ...arr2];
console.log(combinedArr2); // 输出:[1, 2, 3, 4]
虽然两者都可以实现相同的效果,扩展运算符语法更加简洁易读。
扩展运算符的应用场景
- 数组克隆与合并:可以快速复制数组或合并多个数组。
- 对象合并与拷贝:适用于对象的浅拷贝和合并多个对象。
- 简化函数参数传递:可以将数组展开为函数参数列表,避免使用 apply()。
结论
扩展运算符(…)是 ES6 中的一个非常强大且简洁的语法工具,能够高效地处理数组和对象的合并、克隆等操作。它不仅使代码更加简洁,也提高了可读性。特别是在处理不定参数和函数调用时,扩展运算符为开发者提供了更简洁的语法。