JavaScript 原生 API 替代第三方库指南
随着现代浏览器的不断发展,JavaScript 原生 API 已经变得非常强大。许多曾经依赖第三方库的场景,现在都可以使用原生 API 来实现。
为什么使用原生 API?
- 🚀 性能更好 - 原生 API 由浏览器引擎直接实现,执行效率更高
- 📦 减小包体积 - 减少依赖,降低构建产物大小
- 🔧 无需维护 - 原生 API 由浏览器维护,无需担心库的更新和安全问题
- 🌐 更好的兼容性 - 现代浏览器对原生 API 的支持越来越好
替代方案对照表
| 第三方库 | 原生 API 替代 | 说明 |
|---|---|---|
url-parse | new URL() | URL 解析和操作 |
left-pad | ''.padStart() | 字符串左侧填充 |
lodash.last | arr.at(-1) | 获取数组最后一个元素 |
uuid | crypto.randomUUID() | 生成 UUID |
deepclone | structuredClone() | 深拷贝对象 |
numeral | Intl.NumberFormat() | 数字格式化 |
moment | Intl.DateTimeFormat() | 日期时间格式化 |
lodash.get | obj?.prop?.subprop | 安全访问嵌套属性 |
lodash.groupBy | Object.groupBy() | 数组分组 |
downloadjs | URL.createObjectURL() | 文件下载 |
query-string | new URLSearchParams() | URL 参数处理 |
详细使用示例
1. URL 解析 - new URL()
// ❌ 使用 url-parse
import urlParse from 'url-parse';
const parsed = urlParse('https://example.com/path?query=1');
// ✅ 使用原生 URL
const parsed = new URL('https://example.com/path?query=1');
console.log(parsed.hostname); // example.com
console.log(parsed.searchParams.get('query')); // 1
2. 字符串填充 - padStart() / padEnd()
// ❌ 使用 left-pad
import leftPad from 'left-pad';
leftPad('5', 3, '0'); // 005
// ✅ 使用原生 padStart
'5'.padStart(3, '0'); // 005
'5'.padEnd(3, '0'); // 500
3. 数组操作 - at() / slice()
// ❌ 使用 lodash.last
import last from 'lodash.last';
last([1, 2, 3]); // 3
// ✅ 使用原生 at()
[1, 2, 3].at(-1); // 3
// 获取前 n 个元素
[1, 2, 3, 4, 5].slice(0, 3); // [1, 2, 3]
4. 生成 UUID - crypto.randomUUID()
// ❌ 使用 uuid
import { v4 as uuidv4 } from 'uuid';
uuidv4(); // 550e8400-e29b-41d4-a716-446655440000
// ✅ 使用原生 crypto
crypto.randomUUID(); // 550e8400-e29b-41d4-a716-446655440000
5. 深拷贝 - structuredClone()
// ❌ 使用 lodash.cloneDeep
import cloneDeep from 'lodash.clonedeep';
const copy = cloneDeep(obj);
// ✅ 使用原生 structuredClone
const copy = structuredClone(obj);
// ⚠️ 注意:不支持函数、Symbol 等特殊类型
6. 数字格式化 - Intl.NumberFormat()
// ❌ 使用 numeral
import numeral from 'numeral';
numeral(1234567).format('0,0.00'); // 1,234,567.00
// ✅ 使用原生 Intl
new Intl.NumberFormat('zh-CN', {
style: 'decimal',
minimumFractionDigits: 2,
maximumFractionDigits: 2
}).format(1234567); // 1,234,567.00
// 货币格式化
new Intl.NumberFormat('zh-CN', {
style: 'currency',
currency: 'CNY'
}).format(1234.56); // ¥1,234.56
7. 日期时间 - Intl.DateTimeFormat()
// ❌ 使用 moment
import moment from 'moment';
moment().format('YYYY-MM-DD HH:mm:ss');
// ✅ 使用原生 Intl
new Intl.DateTimeFormat('zh-CN', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
hour: '2-digit',
minute: '2-digit',
second: '2-digit',
hour12: false
}).format(new Date()); // 2026/01/03 22:00:00
// 相对时间
new Intl.RelativeTimeFormat('zh-CN', { numeric: 'auto' })
.format(-1, 'day'); // 昨天
8. 安全访问属性 - 可选链 ?.
// ❌ 使用 lodash.get
import get from 'lodash.get';
get(obj, 'user.address.city', '默认值');
// ✅ 使用原生可选链
obj?.user?.address?.city ?? '默认值';
9. 数组分组 - Object.groupBy()
// ❌ 使用 lodash.groupBy
import groupBy from 'lodash.groupby';
groupBy(array, 'category');
// ✅ 使用原生 Object.groupBy (ES2024)
Object.groupBy(array, item => item.category);
// ⚠️ 注意:需要较新的浏览器支持
10. 文件下载 - URL.createObjectURL()
// ❌ 使用 downloadjs
import download from 'downloadjs';
download(blob, 'filename.txt', 'text/plain');
// ✅ 使用原生 API
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'filename.txt';
a.click();
URL.revokeObjectURL(url);
11. URL 参数处理 - URLSearchParams
// ❌ 使用 query-string
import qs from 'query-string';
qs.parse(location.search);
qs.stringify({ key: 'value' });
// ✅ 使用原生 URLSearchParams
const params = new URLSearchParams(location.search);
params.get('key'); // value
params.toString(); // key=value
// 添加/修改参数
params.set('newKey', 'newValue');
浏览器兼容性参考
| API | 最低支持版本 |
|---|---|
URL | Chrome 32+, Firefox 26+, Safari 7+ |
padStart/padEnd | Chrome 57+, Firefox 48+, Safari 10+ |
at() | Chrome 92+, Firefox 90+, Safari 15.4+ |
crypto.randomUUID() | Chrome 92+, Firefox 95+, Safari 15.4+ |
structuredClone() | Chrome 98+, Firefox 94+, Safari 16.4+ |
Intl.* | Chrome 24+, Firefox 29+, Safari 10+ |
可选链 ?. | Chrome 80+, Firefox 74+, Safari 13.1+ |
Object.groupBy() | Chrome 117+, Firefox 119+, Safari 17+ |
URLSearchParams | Chrome 49+, Firefox 44+, Safari 10.1+ |
注意事项
- 检查浏览器兼容性 - 使用原生 API 前请确认目标用户的浏览器支持情况
- Polyfill 方案 - 如需支持旧浏览器,可考虑使用 polyfill
- 功能差异 - 某些原生 API 的功能可能与第三方库不完全相同
- 渐进式迁移 - 建议逐步迁移,先在非关键路径上试用
总结
现代 JavaScript 原生 API 已经非常强大,在大多数场景下可以替代第三方库。合理使用原生 API 可以:
- ✅ 减少项目依赖
- ✅ 提升应用性能
- ✅ 降低维护成本
- ✅ 减小打包体积
在开始新项目或重构旧项目时,优先考虑使用原生 API 是一个明智的选择。
参考资源