传参优于外部变量

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,而不是到处飘全局变量。
相关推荐
QQ1__81151751544 分钟前
Spring boot名城小区物业管理系统信息管理系统源码-SpringBoot后端+Vue前端+MySQL【可直接运行】
前端·vue.js·spring boot
钛态1 小时前
前端微前端架构:大项目的救命稻草还是自找麻烦?
前端·vue·react·web
一粒黑子1 小时前
【实战解析】阿里开源 PageAgent:纯前端 GUI Agent,一行JS让网页支持自然语言操控
前端·javascript·开源
独角鲸网络安全实验室1 小时前
2026微信小程序抓包全解析:从实操落地到合规风控,解锁前端调试新范式
前端·微信小程序·小程序·抓包·系统代理绕过·https证书严格校验·进程隔离
紫微AI1 小时前
前端文本测量成了卡死一切创新的最后瓶颈,pretext实现突破了
前端·人工智能·typescript
GISer_Jing1 小时前
AI前端(From豆包)
前端·aigc·ai编程
IT枫斗者1 小时前
前端部署后如何判断“页面是不是最新”?一套可落地的版本检测方案(适配 Vite/Vue/React/任意 SPA)
前端·javascript·vue.js·react.js·架构·bug
测试修炼手册1 小时前
[测试技术] 深入理解 JSON Web Token (JWT)
前端·json
AI老李1 小时前
2026 年 Web 前端开发的 8 个趋势!
前端
里欧跑得慢1 小时前
15. Web可访问性最佳实践:让每个用户都能平等访问
前端·css·flutter·web