跳到主要内容

JavaScript 函数参数

函数参数简介

在JavaScript中,函数参数是我们传递给函数的值,使函数能够基于这些输入执行特定任务。参数允许我们创建可复用的函数,通过不同的输入值产生不同的结果。

函数参数的基本语法如下:

javascript
function 函数名(参数1, 参数2, ..., 参数n) {
// 函数体
}

基本参数用法

定义和调用带参数的函数

让我们从一个简单的例子开始:

javascript
// 定义带两个参数的函数
function add(a, b) {
return a + b;
}

// 调用函数并传递参数
const result = add(5, 3);
console.log(result); // 输出: 8

在这个例子中,ab是函数add的参数,当我们调用add(5, 3)时,5被赋值给a3被赋值给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

掌握函数参数的各种用法,能够让你的代码更加灵活、强大和易于维护。

练习

为了巩固所学知识,尝试完成以下练习:

  1. 创建一个接受任意数量数字参数并返回其平均值的函数
  2. 编写一个函数,接受一个对象和一个回调函数作为参数,对对象的每个属性应用回调函数
  3. 实现一个函数,可以根据给定的选项对数组进行排序(升序或降序)和过滤

扩展资源