传参优于外部变量

1. 为什么"传参"通常更好?

✅ 1)意图更清晰

javascript 复制代码
function calcPrice(count, taxRate) {  // 一眼就知道需要啥
  return count * 100 * (1 + taxRate);
}

vs

javascript 复制代码
let taxRate = 0.08;

function calcPrice(count) {           // 看不出来还依赖 taxRate
  return count * 100 * (1 + taxRate);
}

传参的时候,函数签名就是"需求清单",别人一看就知道这个函数要什么东西。


✅ 2)更好测、更好复用

  • 传参:写单测时,随便喂各种参数就能测试。
  • 依赖外部变量:你得先改外部变量,或者 mock 环境,麻烦还容易互相干扰。
python 复制代码
# 传参版
def discount(price, ratio):
    return price * ratio

# 外部变量版
RATIO = 0.9
def discount(price):
    return price * RATIO

第一个在测试环境里很好搞:
discount(100, 0.5)discount(100, 0.9) 想测啥测啥。

第二个你要改 RATIO,还小心别影响别的测试用例。


✅ 3)耦合更低

  • 使用外部变量 = 函数和外部环境绑得很死。
  • 传参 = 函数只关心"输入 → 输出",外部只负责提供数据。

耦合高的坏处:

  • 重构时,改一个地方牵一堆东西。
  • 多线程/多协程/多请求下可能踩共享数据(尤其是状态可变的时候)。

✅ 4)并发和异步更安全

比如在 JS 里:

javascript 复制代码
let currentUserId;

async function handleRequest(userId) {
  currentUserId = userId;
  await someAsyncWork();
  log("user: ", currentUserId); // 有可能已经被别的请求改了
}

如果你改成传参:

scss 复制代码
async function handleRequest(userId) {
  await someAsyncWork();
  log("user: ", userId); // 永远是自己的
}

不会被其他并发请求污染。


2. 那什么时候可以用"外部作用域变量"?

不是说"外部变量必死罪",只是要用得克制一点。

✅ 适合用外部作用域的场景

  1. 真正的常量 / 配置,且全局统一

    • 比如:PIMAX_RETRYAPI_BASE_URL 这类 恒定不变 的东西。
    • 或者配置对象:config = {...},在多个地方读。
  2. 工具函数里使用的、明显不应该由调用方决定的东西

    比如日志函数里的全局 logger、时间格式器等,这些属于"环境",而不是"业务参数"。

  3. 闭包做"柯里化"/"部分应用"的时候

    这种用外部变量,反而是清晰的设计:

    javascript 复制代码
    function makeAdder(delta) {
      return function (x) {
        return x + delta;  // 用外部 delta,很自然
      };
    }
    
    const add10 = makeAdder(10);
    add10(5); // 15

    外部变量在这里其实是"构造参数",而返回的函数只暴露一部分参数。

  4. 避免在层层传递一些"框架级上下文"时,可用 DI / 上下文对象

    比如 web 框架里,有类似 requestContext 这种东西,可以通过依赖注入、上下文管理器、ThreadLocal 等访问------这些本质上也是"外部作用域变量"的一种(但通常有框架规范来控制滥用)。


3. 什么时候"绝对不要"用外部变量?

  1. 变量是可变状态(会被改来改去)

    • 比如 currentUser, currentOrder, tempList, cacheData 等。
    • 一改就变"隐形依赖",容易出错、线程不安全。
  2. 函数逻辑高度依赖当前"时刻"的外部状态

    • 比如"点按钮时看全局的 selectedItem 是谁"这种,如果逻辑越来越复杂,会很难排错。
  3. 你自己都开始怀疑"这玩意儿是谁改的?"的时候

    • 说明已经失控了 😂

4. 性能上会不会传参更慢?

一般业务代码里:

  • 传参的开销 = 微乎其微,可以忽略。
  • 把设计搞乱、调试时间翻倍的开销 = 巨大。

除非你在写 极致性能敏感 的底层库(比如内核、编解码核心循环这种),否则别因为"性能"去牺牲可读性和可维护性。

就算是那种场景,也会结合 profiler 真实数据来优化,而不是凭感觉"传参好像慢"。


5. 可以直接拿去用的简单原则

你可以记一个小 checklist:

  1. 这个值会变吗?

    • 会变 → 传参,别用外部变量。
    • 不会变(常量/配置)→ 可以外部,但最好集中管理。
  2. 这个函数能独立拿去写单测吗?

    • 如果不能,因为缺这缺那的"外部状态" → 优先改成传参。
  3. 函数的行为是否能只通过参数来描述?

    • 能 → 传参,多爽。
    • 不能 → 你可能在做"状态机、上下文管理"这类事,考虑用对象封装、类、context,而不是到处飘全局变量。
相关推荐
qq_22589174662 小时前
基于Python+Django餐饮评论大数据分析与智能推荐系统 毕业论文
开发语言·后端·python·信息可视化·数据分析·django
bcbnb2 小时前
网络调试与API测试必修课 Fiddler抓包工具使用教程、代理配置与HTTPS抓包技巧全解析
后端
小小小小宇2 小时前
处理耗时较长的任务笔记
前端
华仔啊2 小时前
解决 XXL-Job 定时任务时间偏差8小时的问题
后端
消失的旧时光-19432 小时前
Flutter Scaffold 全面解析:打造页面骨架的最佳实践(附场景示例 + 踩坑分享)
前端·flutter
三门2 小时前
开源版扣子私有化部署
前端
南山安2 小时前
让 LLM 与外界对话:使用 Function Calling 实现天气查询工具
人工智能·后端·python
天草二十六_简村人2 小时前
docker安装MoneyPrinterTurbo,实现文本转视频的本地私有化部署
后端·docker·ai·容器·ai编程
麦麦大数据2 小时前
F048 体育新闻推荐系统vue+flask
前端·vue.js·flask·推荐算法·体育·体育新闻