惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

美团技术团队
B
Blog RSS Feed
博客园_首页
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Google DeepMind News
Google DeepMind News
D
Docker
Blog — PlanetScale
Blog — PlanetScale
M
MIT News - Artificial intelligence
C
Check Point Blog
The Cloudflare Blog
T
Tailwind CSS Blog
大猫的无限游戏
大猫的无限游戏
量子位
The GitHub Blog
The GitHub Blog
Microsoft Azure Blog
Microsoft Azure Blog
I
InfoQ
T
The Blog of Author Tim Ferriss
博客园 - 【当耐特】
Vercel News
Vercel News
P
Proofpoint News Feed
Hugging Face - Blog
Hugging Face - Blog
V
V2EX
博客园 - 司徒正美

串串狗小刊 ⭐️

Web 出海之域名商、托管商等一定要分开 - 串串狗小刊 - 聊AI、互联网、前端技术 ~ 程序员下班以后做什么副业合适? - 串串狗小刊 - 聊AI、互联网、前端技术 ~ 终极拷问:用户的登录信息放哪里? - 串串狗小刊 - 聊AI、互联网、前端技术 ~ 5个 link 标签,突破前端性能瓶颈! - 串串狗小刊 Web 出海让你结束上班时代! - 串串狗小刊 - 聊AI、互联网、前端技术 ~ 注意!程序员不要使用 设计模式 了! - 串串狗小刊 Web 出海之品牌站如何应对被别人侵权 - 串串狗小刊 - 聊AI、互联网、前端技术 ~ Web 出海之一些广告流量主方案和 SaaS 站没必要搞社区 - 串串狗小刊 年轻人怎么抓住 AI 发展的风口? - 串串狗小刊 为什么 GO 语言地位很尴尬? - 串串狗小刊 Web 出海必备的外链列表 - 串串狗小刊 - 聊AI、互联网、前端技术 ~ 我的 Web 3D 世界梦 - 串串狗小刊 OPC Web 出海之图视频的 AI 供应商渠道和简单外链 - 串串狗小刊 简单聊聊我的 Nodejs 世界观 - 串串狗小刊 Web 出海快速判断关键词法和推荐 3 个 SKILL - 串串狗小刊 Web 出海之演示建站盈利和朋友 Reyn 的教训 阅读源代码前要运行的 5 条 Git 命令 - 串串狗小刊 介绍几组我一直在使用的 Codex 插件 我观看哥飞年终会议复盘的 Web 出海笔记(下) - 串串狗小刊 观看哥飞年终会议复盘的 8 个 Web 出海笔记 - 串串狗小刊 Codex 敞开用的技巧和谷歌趋势的参考词 - 串串狗小刊 - 聊AI、互联网、前端技术 ~ Web 出海之外链提交频率和如何不花 Token 处理代码 - 串串狗小刊 程序员现在的最佳副业 ~ Web 出海 - 串串狗小刊 如何设计良好的 API - 串串狗小刊 - 聊AI、互联网、前端技术 ~ 你跟 AI 对话后会发生什么? - 串串狗小刊 出海 Web 之 GSC 里的曝光量和点击量和外链的关系 - 串串狗小刊 出海 Web 不要 恋战 新词游戏站 - 串串狗小刊 无港卡开通 Stripe 收款和 Nofollow 转 Dofollow 技巧 - 串串狗小刊 DeepSeek 发布氮气加速器 DSpark!可惜好东西又开源了 - 串串狗小刊 简单聊聊出海 Web 的游戏站 - 串串狗小刊
求求你别再 .filter().map().sort() 了 - 串串狗小刊
独元殇 · 2026-04-25 · via 串串狗小刊 ⭐️

今天在这里,我吐槽一下 JavaScript 的链式调用,我觉得虽然有这个语法,但是我们最好永远都别用(就像这样,这是我以前真实项目里出现的代码),起码谨慎用:

const topActiveUsers = users
  .filter(item => item !== null && item !== undefined)  // 过滤空
  .filter(person => person.active === true)  // 是否激活
  .map(profile => profile.name)  // 提取出姓名
  .filter(fullName => fullName && fullName.length > 0)  // 过滤空
  .map(displayName => displayName.trim())
  .sort((a, b) => a.localeCompare(b))  // 排序
  .slice(0, 5)  // 只要前 5 个
  .concat();  // 返回新数组

当年我很喜欢这样写,显得我很牛啊!干干净净,看起来还舒服。

但是,慢慢我就发现,极其难维护!读起来很累。我也不知道这个语法是哪个天才想起来的。这语法相当反人类!

编程语言,本身是在写步骤的,步骤可以上下调整,这个一眼看去,貌似是在写步骤,实际上根本不是!这其实是一个整体!维护时,拆起来很麻烦,一转眼半个小时过去了。

如果,这样摊开来写,反而看起来啰嗦,但更友好了:

const validUsers = users.filter(item => item);
const activeUsers = validUsers.filter(person => person.active);
const userNames = activeUsers.map(profile => profile.name);
const nonEmptyNames = userNames.filter(fullName => fullName);
const trimmedNames = nonEmptyNames.map(displayName => displayName.trim());
const sortedNames = trimmedNames.sort((a, b) => a.localeCompare(b));
const topFiveNames = sortedNames.slice(0, 5);
const topActiveUsers = topFiveNames.concat();

起码前面每个变量,都有名有姓,让人视觉上能喘一口气。

而且有了问题,我可以从中间去 console ,可以慢慢琢么,如果是链式,就做梦吧。

有个大佬说过:「如果一个系统很长时间不出错,它的设计就是良好的。如果你进一步看了代码,脱口而出:"哈,这比我想的要简单",或者"这个部分不用我操心,即使出问题也容易解决",它的设计就是优秀的」。

显而意见,摊开写更好。

当然,也不是没有优点。

还有一个场景,是 Promise 异步。

教材上,一般都是这样默认安装链式写的:

const data = await fetchMembers()
  .then(result => result.json())
  .then(list => list.filter(item => item.isActive))
  .then(list => list.map(item => item.nickname));

猛地一看,好像很简洁舒服,但是,我更建议这样写:

const response = await fetchMembers();
const memberList = await response.json();
const activeMembers = memberList.filter(item => item.isActive);
const data = activeMembers.map(item => item.nickname);

理解起来也舒服不少。

如果他长度比较短,那还是可以接受的。

比如:

members.map(p => p.nickname)  // 一步链式
members.filter(p => p.isActive).map(p => p.nickname)  // 两步链式

两步以内,还是可以接受的。

大于两步,一定不要用链式!