javascript函数式编程是什么_纯函数与副作用如何理解?

发布时间 - 2025-12-31 00:00:00    点击率:
纯函数需同时满足输入完全决定输出且无副作用;如pureAdd是纯函数,impureInc因修改外部状态而非纯;slice不改原数组是纯的,splice等会修改原数组属副作用;副作用须显式隔离、集中管控并可测试。

JavaScript 函数式编程不是加个 mapfilter 就算数,它的核心是用「纯函数」组织逻辑、把「副作用」明确隔离出来——否则只是披着函数外衣的过程式代码。

怎么一眼识别纯函数?两个硬指标必须同时满足

判断一个函数是不是纯函数,只看两件事:输入是否完全决定输出?执行过程有没有“碰”外部世界?

  • 确定性:相同参数调用,返回值必须严格一致。比如 Math.pow(2, 3) 永远是 8,不依赖时间、随机数、全局变量或配置项
  • 无副作用:不能修改传入的引用类型(如 arr.push())、不能改全局变量、不能操作 document、不能发请求、不能 console.log(哪怕只是调试)
function pureAdd(a, b) {
  return a + b; // ✅ 纯:只靠参数,不碰外界
}

let count = 0;
function impureInc() {
  return ++count; // ❌ 非纯:依赖并修改外部状态
}

为什么 splice 是“坏同学”,slice 却是“好榜样”?

数组方法是最容易踩坑的日常场景。关键看它是否「改变原数组」——这属于典型的副作用。

  • slice(start, end) 返回新数组,原数组不变 → 符合纯函数精神(只要不传入 mutable 对象作为参数本身)
  • splice(start, deleteCount, ...items) 直接修改原数组 → 副作用立现,哪怕你没用返回值
  • 同理:sort()reverse()fill() 全部非纯;而 map()filter()flatMap() 默认纯(前提是回调函数也纯)
const nums = [1, 2, 3];
nums.slice(0, 2); // [1, 2] → nums 还是 [1, 2, 3]
nums.splice(0, 2); // [1, 2] → nums 变成 [3]!副作用已发生

副作用不是敌人,但必须“显式声明”和“集中管控”

完全没副作用的程序等于没用——你要渲染页面、要存 localStorage、要发请求。问题不在“有没有”,而在“谁负责、在哪发生、能否测试”。

立即学习“Java免费学习笔记(深入)”;

  • 把副作用从计算逻辑中抽离,变成可替换的参数:比如把 Email.send(user) 改成 sendEmail(EmailService, user)
  • 在框架层统一收口:React 的 useEffect、RxJS 的 subscribe、Redux-Saga 的 call,都是为副作用提供可控的“出口”
  • 测试时直接 mock 副作用:传一个假的 fetch 函数进去,断言它是否被正确调用,而不用真连网络
// ❌ 副作用藏在深处,无法测试
function signUp(name) {
  const user = db.save({ name });
  email.send(user); // 调用真实邮件服务
  return user;
}

// ✅ 副作用外移,逻辑可测
function signUp(db, email, name) {
  const user = db.save({ name });
  email.send(user);
  return user;
}

最容易被忽略的一点:**对象和数组作为参数传入时,函数内部对它们属性或元素的修改,就算副作用**——哪怕没动变量名本身。纯函数要求“不碰传入的引用”,只读或深拷贝后再操作。


# react  # javascript  # java  # js  # 回调函数  # ai  # 为什么  # red 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel怎么写单元测试_PHPUnit在Laravel项目中的基础测试入门  网站图片在线制作软件,怎么在图片上做链接?  Laravel怎么实现软删除SoftDeletes_Laravel模型回收站功能与数据恢复【步骤】  Laravel怎么实现模型属性的自动加密  JS经典正则表达式笔试题汇总  Laravel如何使用Service Container和依赖注入?(代码示例)  php485函数参数是什么意思_php485各参数详细说明【介绍】  国美网站制作流程,国美电器蒸汽鍋怎么用官方网站?  香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南  韩国代理服务器如何选?解析IP设置技巧与跨境访问优化指南  Laravel如何使用withoutEvents方法临时禁用模型事件  Laravel如何使用查询构建器?(Query Builder高级用法)  用yum安装MySQLdb模块的步骤方法  Laravel请求验证怎么写_Laravel Validator自定义表单验证规则教程  绝密ChatGPT指令:手把手教你生成HR无法拒绝的求职信  Android Socket接口实现即时通讯实例代码  ChatGPT常用指令模板大全 新手快速上手的万能Prompt合集  什么是javascript作用域_全局和局部作用域有什么区别?  C++时间戳转换成日期时间的步骤和示例代码  智能起名网站制作软件有哪些,制作logo的软件?  如何在IIS7上新建站点并设置安全权限?  米侠浏览器网页图片不显示怎么办 米侠图片加载修复  Laravel如何使用Blade模板引擎?(完整语法和示例)  Swift中switch语句区间和元组模式匹配  android nfc常用标签读取总结  Laravel怎么返回JSON格式数据_Laravel API资源Response响应格式化【技巧】  什么是JavaScript解构赋值_解构赋值有哪些实用技巧  Laravel如何发送系统通知?(Notification渠道示例)  如何在建站主机中优化服务器配置?  简单实现jsp分页  Laravel全局作用域是什么_Laravel Eloquent Global Scopes应用指南  高防服务器租用指南:配置选择与快速部署攻略  Android自定义listview布局实现上拉加载下拉刷新功能  如何使用 jQuery 正确渲染 Instagram 风格的标签列表  如何基于云服务器快速搭建网站及云盘系统?  Laravel 419 page expired怎么解决_Laravel CSRF令牌过期处理  长沙做网站要多少钱,长沙国安网络怎么样?  Python面向对象测试方法_mock解析【教程】  打开php文件提示内存不足_怎么调整php内存限制【解决方案】  制作公司内部网站有哪些,内网如何建网站?  EditPlus中的正则表达式实战(6)  CSS3怎么给轮播图加过渡动画_transition加transform实现【技巧】  Laravel如何优化应用性能?(缓存和优化命令)  jquery插件bootstrapValidator表单验证详解  详解Huffman编码算法之Java实现  Laravel怎么使用Markdown渲染文档_Laravel将Markdown内容转HTML页面展示【实战】  Laravel如何处理跨站请求伪造(CSRF)保护_Laravel表单安全机制与令牌校验  Laravel如何使用Spatie Media Library_Laravel图片上传管理与缩略图生成【步骤】  教你用AI将一段旋律扩展成一首完整的曲子  Win11应用商店下载慢怎么办 Win11更改DNS提速下载【修复】