JavaScript 函数参数
函数参数简介
在JavaScript中,函数参数是我们传递给函数的值,使函数能够基于这些输入执行特定任务。参数允许我们创建可复用的函数,通过不同的输入值产生不同的结果。
函数参数的基本语法如下:
javascript
function 函数名(参数1, 参数2, ..., 参数n) {
// 函数体
}
基本参数用法
定义和调用带参数的函数
让我们从一个简单的例子开始:
javascript
// 定义带两个参数的函数
function add(a, b) {
return a + b;
}
// 调用函数并传递参数
const result = add(5, 3);
console.log(result); // 输出: 8
在这个例子中,a
和b
是函数add
的参数,当我们调用add(5, 3)
时,5
被赋值给a
,3
被赋值给b
。
参数的顺序很重要
参数的顺序决定了值如何分配给参数:
javascript
function greet(name, message) {
return `${message}, ${name}!`;
}
// 正确顺序的参数
console.log(greet("小明", "你好")); // 输出: 你好, 小明!
// 错误顺序的参数
console.log(greet("你好", "小明")); // 输出: 小明, 你好! (不符合预期)
参数默认值
ES6引入了参数默认值,允许在参数未提供或为undefined
时使用预设值:
javascript
function greet(name = "访客", message = "欢迎") {
return `${message}, ${name}!`;
}
console.log(greet()); // 输出: 欢迎, 访客!
console.log(greet("小红")); // 输出: 欢迎, 小红!
console.log(greet("小蓝", "你好")); // 输出: 你好, 小蓝!
提示
参数默认值是ES6的新特性,提高了函数的灵活性和代码的简洁性。
不定参数数量
JavaScript提供了多种处理不定数量参数的方法。
arguments对象
在函数内部,arguments
对象包含了传递给函数的所有参数:
javascript
function sum() {
let total = 0;
for (let i = 0; i < arguments.length; i++) {
total += arguments[i];
}
return total;
}
console.log(sum(1, 2, 3)); // 输出: 6
console.log(sum(1, 2, 3, 4, 5)); // 输出: 15
警告
虽然arguments
对象在所有函数中都可用,但它不是一个真正的数组,没有数组的方法。现代JavaScript推荐使用剩余参数语法。
剩余参数(Rest Parameters)
ES6引入的剩余参数语法允许我们将不定数量的参数表示为真正的数组:
javascript
function sum(...numbers) {
return numbers.reduce((total, num) => total + num, 0);
}
console.log(sum(1, 2, 3)); // 输出: 6
console.log(sum(1, 2, 3, 4, 5)); // 输出: 15
剩余参数必须是函数参数列表中的最后一个参数:
javascript
// 正确用法
function printInfo(name, age, ...hobbies) {
console.log(`名字: ${name}, 年龄: ${age}`);
console.log(`爱好: ${hobbies.join(', ')}`);
}
printInfo("小明", 25, "读书", "跑步", "游泳");
// 输出:
// 名字: 小明, 年龄: 25
// 爱好: 读书, 跑步, 游泳
解构参数
ES6的解构赋值也可以应用于函数参数,使代码更简洁:
对象解构
javascript
// 使用对象解构获取特定属性
function displayUser({ name, age, city = "未知" }) {
console.log(`用户 ${name} 今年 ${age} 岁,来自 ${city}`);
}
const user = {
name: "小李",
age: 30,
occupation: "工程师"
};
displayUser(user); // 输出: 用户 小李 今年 30 岁,来自 未知
数组解构
javascript
// 使用数组解构获取特定位置的元素
function getFirstAndLast([first, ...rest]) {
return {
first,
last: rest.pop()
};
}
const result = getFirstAndLast([1, 2, 3, 4, 5]);
console.log(result); // 输出: { first: 1, last: 5 }
参数传递方式
理解JavaScript的参数传递机制对于正确使用函数至关重要。
基本类型参数
基本类型(如字符串、数字、布尔值)是按值传递的:
javascript
function modifyValue(x) {
x = x * 2;
console.log("函数内:", x);
}
let num = 10;
console.log("调用前:", num); // 输出: 调用前: 10
modifyValue(num); // 输出: 函数内: 20
console.log("调用后:", num); // 输出: 调用后: 10(值不变)
引用类型参数
引用类型(如对象、数组)是按引用传递的:
javascript
function modifyObject(obj) {
obj.name = "已修改";
}
const person = { name: "原始名称" };
console.log("修改前:", person.name); // 输出: 修改前: 原始名称
modifyObject(person);
console.log("修改后:", person.name); // 输出: 修改后: 已修改
高级参数技巧
回调函数作为参数
函数可以作为另一个函数的参数传递,这是JavaScript中常见的模式:
javascript
function processData(data, callback) {
// 处理数据
const processed = `处理后的${data}`;
// 完成后调用回调函数
callback(processed);
}
// 定义回调函数
function displayResult(result) {
console.log(`结果是: ${result}`);
}
// 传递回调函数
processData("原始数据", displayResult);
// 输出: 结果是: 处理后的原始数据
// 使用匿名函数作为回调
processData("新数据", function(result) {
console.log(`处理完成: ${result}`);
});
// 输出: 处理完成: 处理后的新数据
立即调用的函数表达式(IIFE)中的参数
IIFE是一种自执行的函数,可以接受参数:
javascript
(function(name, greeting) {
console.log(`${greeting}, ${name}!`);
})("JavaScript学习者", "你好");
// 输出: 你好, JavaScript学习者!
实际应用案例
案例1: 购物车计算器
javascript
function calculateCart(items, { discount = 0, tax = 0.05 } = {}) {
// 计算商品总价
const subtotal = items.reduce((total, item) => total + item.price * item.quantity, 0);
// 应用折扣
const discountAmount = subtotal * discount;
// 计算税额
const taxAmount = (subtotal - discountAmount) * tax;
// 计算最终价格
const total = subtotal - discountAmount + taxAmount;
return {
subtotal,
discount: discountAmount,
tax: taxAmount,
total
};
}
// 使用示例
const cartItems = [
{ name: "笔记本", price: 10, quantity: 2 },
{ name: "钢笔", price: 50, quantity: 1 },
{ name: "橡皮", price: 5, quantity: 3 }
];
// 无折扣计算
const regularResult = calculateCart(cartItems);
console.log(regularResult);
// 输出类似: { subtotal: 95, discount: 0, tax: 4.75, total: 99.75 }
// 有折扣计算
const discountResult = calculateCart(cartItems, { discount: 0.1, tax: 0.08 });
console.log(discountResult);
// 输出类似: { subtotal: 95, discount: 9.5, tax: 6.84, total: 92.34 }
案例2: 数据筛选器
javascript
function filterData(data, options = {}) {
const {
minAge = 0,
maxAge = Infinity,
city = null,
sortBy = null,
limit = data.length
} = options;
// 过滤数据
let result = data.filter(person => {
if (person.age < minAge || person.age > maxAge) return false;
if (city && person.city !== city) return false;
return true;
});
// 排序数据
if (sortBy) {
result.sort((a, b) => a[sortBy] > b[sortBy] ? 1 : -1);
}
// 限制结果数量
return result.slice(0, limit);
}
// 示例数据
const people = [
{ name: "张三", age: 25, city: "北京" },
{ name: "李四", age: 30, city: "上海" },
{ name: "王五", age: 22, city: "北京" },
{ name: "赵六", age: 35, city: "广州" }
];
// 使用不同选项调用
console.log(filterData(people, { minAge: 25, city: "北京" }));
// 输出: [{ name: "张三", age: 25, city: "北京" }]
console.log(filterData(people, { sortBy: "age", limit: 2 }));
// 输出: [{ name: "王五", age: 22, city: "北京" }, { name: "张三", age: 25, city: "北京" }]
总结
JavaScript函数参数是构建灵活、可复用函数的基础:
- 基本参数允许我们将值传递给函数
- 默认参数处理缺失的参数值
- 剩余参数处理不确定数量的参数
- 解构参数使代码更简洁
- 参数的传递方式取决于数据类型(基本类型按值传递,引用类型按引用传递)
- 函数作为参数可以实现回调模式
- 参数结合对象选项可以创建灵活的API
掌握函数参数的各种用法,能够让你的代码更加灵活、强大和易于维护。
练习
为了巩固所学知识,尝试完成以下练习:
- 创建一个接受任意数量数字参数并返回其平均值的函数
- 编写一个函数,接受一个对象和一个回调函数作为参数,对对象的每个属性应用回调函数
- 实现一个函数,可以根据给定的选项对数组进行排序(升序或降序)和过滤