欢迎光临新沂市中国白事服务网
详情描述

1. 基本参数传递(值传递)

// 基本类型是值传递
function changeValue(x) {
    x = 10;  // 不影响外部变量
}

let num = 5;
changeValue(num);
console.log(num); // 5,不变

2. 对象/数组参数(引用传递)

// 对象和数组是引用传递
function changeObject(obj) {
    obj.name = "changed";  // 会影响原对象
}

let person = { name: "John" };
changeObject(person);
console.log(person.name); // "changed"

3. 避免意外修改参数的解决方案

方案1:使用默认参数

// ES6默认参数
function greet(name = "Guest", age = 18) {
    return `Hello ${name}, age ${age}`;
}

方案2:创建副本

function safeModify(obj) {
    // 创建副本
    const newObj = { ...obj };  // 浅拷贝
    newObj.name = "changed";
    return newObj;  // 返回新对象
}

// 数组同理
function safeArrayModify(arr) {
    return [...arr, "new item"];  // 返回新数组
}

方案3:使用解构赋值

// 解构参数
function processUser({ name, age = 25 } = {}) {
    return `${name} is ${age} years old`;
}

// 混合解构
function processData({ 
    name, 
    settings: { theme = 'light', notifications = true } = {} 
} = {}) {
    console.log(name, theme);
}

方案4:Rest参数

// 收集剩余参数
function sum(...numbers) {
    return numbers.reduce((acc, num) => acc + num, 0);
}

console.log(sum(1, 2, 3, 4)); // 10

4. 高级技巧

参数验证

function createUser({
    name,
    age,
    email,
    isAdmin = false
} = {}) {
    // 参数验证
    if (!name || typeof name !== 'string') {
        throw new Error('Name is required and must be a string');
    }
    if (age < 0) {
        throw new Error('Age cannot be negative');
    }

    return { name, age, email, isAdmin };
}

柯里化函数

// 函数柯里化
const multiply = (a) => (b) => a * b;
const double = multiply(2);
console.log(double(5)); // 10

惰性求值

function lazyCompute(value, computeFn = () => value) {
    return computeFn();
}

console.log(lazyCompute(5)); // 5
console.log(lazyCompute(null, () => 10 * 10)); // 100

5. 常见问题解决

Q1:如何设置可选参数?

// 方法1:使用默认值
function log(message, prefix = "LOG: ") {
    console.log(prefix + message);
}

// 方法2:检查undefined
function log(message, prefix) {
    const actualPrefix = prefix !== undefined ? prefix : "LOG: ";
    console.log(actualPrefix + message);
}

Q2:如何处理多个可选参数?

// 使用对象参数
function createElement({
    tag = 'div',
    text = '',
    className = '',
    onClick = null
} = {}) {
    const el = document.createElement(tag);
    el.textContent = text;
    el.className = className;
    if (onClick) el.onclick = onClick;
    return el;
}

Q3:参数顺序混乱?

// 使用命名参数模式
function connect({
    host = 'localhost',
    port = 8080,
    timeout = 5000,
    retry = 3
}) {
    console.log(`Connecting to ${host}:${port}`);
}

// 调用清晰明了
connect({ host: 'example.com', port: 3000 });

最佳实践建议:

优先使用解构参数提高代码可读性 对可能被修改的对象参数进行深拷贝(如果需要保持原对象不变) 使用默认参数替代复杂的条件检查 参数过多时使用对象参数 始终验证关键参数的类型和有效性

通过合理使用这些技巧,可以避免JavaScript函数参数处理中的常见问题。