1. 为什么要"告别"?
- 规范已打 🚩 Deprecated:浏览器随时下架,埋得越深爆得越惨
- 性能/体积/安全:老 API 常阻塞线程、无权限模型、包体积爆炸
- 面试必问:能讲清"为什么不用 + 怎么迁"是高分项
以下 10 组案例,95% 的代码库还能搜到,但官方文档早已不建议使用。
2. 一图速览
# | 过时 API / 库 | 典型场景 | 官方替代 | 浏览器支持 |
---|---|---|---|---|
1 | document.execCommand |
富文本、复制 | navigator.clipboard |
96% |
2 | 同步 XMLHttpRequest |
导出 Excel | fetch / axios |
98% |
3 | escape /unescape |
URL 编码 | encodeURIComponent |
100% |
4 | String.substr |
截后缀 | slice /substring |
100% |
5 | Event.keyCode |
回车 13 | Event.key |
97% |
6 | window.event |
IE 全局事件 | 事件参数 e |
100% |
7 | trimLeft/trimRight |
去空白 | trimStart/trimEnd |
98% |
8 | showModalDialog |
阻塞弹窗 | <dialog> |
已移除 |
9 | Moment.js | 日期格式化 | date-fns / luxon / Temporal |
95% |
10 | jQuery | DOM & Ajax | 原生 ES6+ / React / Vue | 98% |
3. 逐个详解 & 最小迁移代码
① document.execCommand
------ 富文本 & 剪贴板
问题 :W3C 停止维护,行为差异大,有 XSS 风险
替代 :navigator.clipboard
(基于 Promise + 权限 API)
js
// 老
document.execCommand('copy');
// 新
await navigator.clipboard.writeText('hello');
低端机兜底:降级回
execCommand
② 同步 XMLHttpRequest
------ 冻结主线程
问题 :官方强烈不建议 ;Chrome 已报 Deprecation 警告
替代 :fetch
(异步 + Stream)
js
// 老
const xhr = new XMLHttpRequest();
xhr.open('GET', '/api', false); // 同步
xhr.send();
// 新
const res = await fetch('/api');
const data = await res.json();
③ escape/unescape
------ 非标准百分号编码
问题 :中文变 %u4E2D%u6587
,+/@ 不编码
替代 :encodeURIComponent
js
escape('中文+abc'); // %u4E2D%u6587+abc
encodeURIComponent('中文+abc'); // %E4%B8%AD%E6%96%87%2Babc
④ String.substr(start, length)
------ 语义混乱
问题 :ECMA-262 标为 legacy
替代 :slice
(支持负数索引)
js
const ext = fileName.slice(fileName.lastIndexOf('.'));
⑤ Event.keyCode
------ 数值随布局变化
问题 :UI Events spec 已废弃
替代 :Event.key
(可读字符串)
js
document.addEventListener('keydown', e => {
if (e.key === 'Enter') { /* 回车 */ }
if (e.key === 'Escape') { /* ESC */ }
});
⑥ window.event
(IE 全局事件)
问题 :非标准,严格模式直接报错
替代 :事件参数 e
js
btn.onclick = (e) => {
console.log(e.target); // 足够
};
⑦ trimLeft/trimRight
------ 命名不统一
问题 :ECMA 2020 起官方别名改为 trimStart/trimEnd
迁移:
js
str.trimStart(); // 去左
str.trimEnd(); // 去右
⑧ showModalDialog
------ 同步阻塞弹窗
现状 :Chrome 43 起已移除
替代 :原生 <dialog>
(非阻塞 + 可样式化)
html
<dialog id="d">
<p>Hi</p>
<button onclick="d.close()">关闭</button>
</dialog>
<script>d.showModal();</script>
⑨ Moment.js ------ 66 KB 的"日期巨头"
问题 :2020 起官方进入维护模式 ,不再加新功能;包体积大
替代:
- date-fns(tree-shaking,按需引)
- luxon(时区友好)
- Temporal(原生草案,2025 已 Chrome 95+ 实验旗)
js
// Moment
moment().format('YYYY-MM-DD');
// date-fns
import { format } from 'date-fns';
format(new Date(), 'yyyy-MM-dd');
⑩ jQuery ------ "百万网站"历史债
现状 :BuiltWith 统计全球 Top 1M 网站 78% 仍引用 ,但新立项使用率 < 6% (State of JS 2024)
替代:
- DOM:
querySelector
+addEventListener
- Ajax:
fetch
- 动画:Web Animations API / CSS
transition
- 链式:可选链
?.
+ 空值合并??
js
// jQuery
$('#btn').click(() => $.get('/api', console.log));
// 原生
document.querySelector('#btn')
.addEventListener('click', () => fetch('/api').then(r => r.json()).then(console.log));
4. 老项目如何"无痛"批量扫描
- ESLint 官方插件
npm i -D eslint-plugin-deprecation
一键标出所有@deprecated
调用 - jscodeshift 脚本
把substr
→slice
、keyCode
→key
全项目自动替换 - Can I use + Babel 插件
确认替代 API 的最低浏览器版本,再决定要不要兜底
5. 结论 & 行动清单
动作 | 优先级 |
---|---|
新代码直接不用左侧 API | 🔴 必须 |
老代码lint 报错 →codemod →回归测试 | 🟡 1 个 Sprint |
剪贴板、网络、日期优先迁,ROI 最高 | 🟢 本周 |
把这篇文章丢进团队 Wiki,下次 Code Review 再看到 execCommand
或 Moment.js
,就能有理有据地拒绝了。
6. 参考资料
: 51CTO《2025 年该淘汰的五个 JavaScript 库》2024-12
: 稀土掘金《2025 年该淘汰的 5 个 JavaScript 库》2024-12
: CSDN《这些过时的前端技术请不要再继续学了!》2023-10
: 21CTO《2025 年你应该告别的 5 个 JavaScript 库》2024-12
: 知乎专栏《2024 总结下前端现状!》2025-02
如果对你有帮助,点个「赞」再走呗~