JavaScript 工具函数简介 #
什么是工具函数? #
工具函数(Utility Functions)是一类专门用于解决特定问题的、可复用的代码片段。它们通常具有以下特点:
text
┌─────────────────────────────────────────────────────────────┐
│ 工具函数特点 │
├─────────────────────────────────────────────────────────────┤
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 单一职责 │ │ 无副作用 │ │ 可测试 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 高复用 │ │ 易维护 │ │ 可组合 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
工具函数的定义 #
javascript
function formatDate(date) {
const d = new Date(date);
const year = d.getFullYear();
const month = String(d.getMonth() + 1).padStart(2, '0');
const day = String(d.getDate()).padStart(2, '0');
return `${year}-${month}-${day}`;
}
formatDate(new Date());
为什么需要工具函数? #
开发中的常见问题 #
text
问题场景:
1. 重复代码
┌─────────────────────────────────────────┐
│ 文件A: 日期格式化代码 │
│ 文件B: 相同的日期格式化代码 │
│ 文件C: 又是相同的日期格式化代码 │
└─────────────────────────────────────────┘
问题:修改时需要改多处,容易遗漏
2. 代码质量参差不齐
┌─────────────────────────────────────────┐
│ 开发者A: 实现方式1 │
│ 开发者B: 实现方式2 │
│ 开发者C: 实现方式3 │
└─────────────────────────────────────────┘
问题:风格不统一,维护困难
3. 边界条件处理不足
┌─────────────────────────────────────────┐
│ 正常情况: 正常工作 │
│ 边界情况: 报错或异常 │
└─────────────────────────────────────────┘
问题:Bug 频发,稳定性差
工具函数的解决方案 #
javascript
import { formater } from './utils/date';
const date1 = formater(Date.now(), 'yyyy-MM-dd');
const date2 = formater('2026-04-04', 'yyyy/MM/dd');
const date3 = formater(new Date(), 'MM-dd HH:mm');
工具函数的分类 #
1. 数据处理类 #
javascript
export const deepCopy = (obj, map = new WeakMap()) => {
if (typeof obj !== 'object' || obj === null) {
return obj;
}
if (map.has(obj)) {
return map.get(obj);
}
const clone = Array.isArray(obj) ? [] : {};
map.set(obj, clone);
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
clone[key] = deepCopy(obj[key], map);
}
}
return clone;
};
2. 字符串处理类 #
javascript
export const getCharLength = (str) => {
let length = 0;
for (let i = 0; i < str.length; i++) {
const charCode = str.charCodeAt(i);
length += (charCode >= 0x4E00 && charCode <= 0x9FFF) ? 2 : 1;
}
return length;
};
getCharLength('Hello世界');
3. 日期时间类 #
javascript
export const formater = (time, format = '') => {
const timeInfo = getTimeInfo(time);
if (!timeInfo) return '';
const { yyyy, MM, dd, hh, mm, ss, HH } = timeInfo;
return format
.replace(/yyyy/, yyyy)
.replace(/MM/, MM)
.replace(/dd/, dd)
.replace(/HH/, HH)
.replace(/hh/, hh)
.replace(/mm/, mm)
.replace(/ss/, ss);
};
4. 网络请求类 #
javascript
export const getQueryString = (name) => {
const reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
const r = window.location.search.slice(1).match(reg);
if (r != null) {
return decodeURIComponent(r[2]);
}
return '';
};
5. 存储操作类 #
javascript
const store = {
get(key) {
const value = localStorage.getItem(key);
try {
const parsed = JSON.parse(value) || {};
const { expires = '', data = null } = parsed;
if (expires && new Date(expires) < new Date()) {
store.remove(key);
return null;
}
return data;
} catch {
return null;
}
},
set(key, value, expires) {
localStorage.setItem(key, JSON.stringify({
expires,
data: value
}));
},
remove(key) {
localStorage.removeItem(key);
}
};
工具函数的设计原则 #
1. 单一职责原则 #
javascript
function formatDate(date) {
return formater(date, 'yyyy-MM-dd');
}
function formatTime(date) {
return formater(date, 'HH:mm:ss');
}
function formatDateTime(date) {
return formater(date, 'yyyy-MM-dd HH:mm:ss');
}
2. 纯函数原则 #
javascript
const add = (a, b) => a + b;
add(1, 2);
add(1, 2);
add(1, 2);
3. 防御性编程 #
javascript
export const getCookie = (name) => {
if (!name) return null;
try {
const reg = new RegExp('(^| )' + name + '=([^;]*)(;|$)');
const match = document.cookie.match(reg);
return match ? decodeURIComponent(match[2]) : null;
} catch (e) {
console.error('Cookie 读取失败:', e);
return null;
}
};
4. 可配置性 #
javascript
export const formatFileSize = (size, options = {}) => {
const {
precision = 2,
units = ['B', 'KB', 'MB', 'GB', 'TB']
} = options;
let filesize = size;
let i = 0;
while (filesize >= 1024 && i < units.length - 1) {
filesize /= 1024;
i++;
}
return `${filesize.toFixed(precision)}${units[i]}`;
};
formatFileSize(1024);
formatFileSize(1024 * 1024, { precision: 3 });
工具函数 vs 第三方库 #
对比分析 #
| 特性 | 自定义工具函数 | Lodash | Underscore | Ramda |
|---|---|---|---|---|
| 体积 | 极小(按需) | ~70KB | ~20KB | ~45KB |
| 定制性 | 极高 | 中等 | 中等 | 高 |
| 学习成本 | 低 | 中等 | 低 | 高 |
| 功能丰富度 | 按需开发 | 非常丰富 | 丰富 | 丰富 |
| 函数式编程 | 支持 | 支持 | 支持 | 强调 |
| Tree-shaking | 完美支持 | 支持 | 一般 | 支持 |
选择建议 #
text
选择自定义工具函数:
├── 项目体积敏感
├── 需求明确且有限
├── 需要高度定制
└── 团队有维护能力
选择第三方库:
├── 项目复杂度高
├── 需要大量工具函数
├── 快速开发优先
└── 团队熟悉该库
工具函数的应用场景 #
1. 表单验证 #
javascript
export const validators = {
required: (value) => !!value || '此项为必填',
email: (value) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value) || '邮箱格式不正确',
phone: (value) => /^1[3-9]\d{9}$/.test(value) || '手机号格式不正确',
minLength: (min) => (value) => value.length >= min || `最少${min}个字符`,
maxLength: (max) => (value) => value.length <= max || `最多${max}个字符`
};
validators.email('test@example.com');
validators.phone('13800138000');
2. 数据转换 #
javascript
export const rgb2hex = (rgb = []) => {
return '#' + rgb.map(item => {
let value = item.toString(16);
return value.length === 1 ? `0${value}` : value;
}).join('');
};
export const hex2rgb = (hex) => {
let _hex = hex[0] === '#' ? hex.slice(1) : hex;
const [a, b, c, d, e, f] = _hex.split('');
return [parseInt(a + b, 16), parseInt(c + d, 16), parseInt(e + f, 16)];
};
rgb2hex([255, 128, 0]);
hex2rgb('#ff8000');
3. 设备检测 #
javascript
export const isMobileAgent = () => {
const userAgent = navigator.userAgent;
const reg = /iphone|ipod|ipad|android|mobile/;
return reg.test(userAgent.toLowerCase());
};
export const getDeviceInfo = () => {
const ua = navigator.userAgent;
return {
isMobile: /mobile/i.test(ua),
isIOS: /iphone|ipad/i.test(ua),
isAndroid: /android/i.test(ua),
isWeChat: /micromessenger/i.test(ua)
};
};
工具函数的组织方式 #
1. 按功能模块组织 #
text
utils/
├── url.js # URL 处理
├── cookie.js # Cookie 操作
├── date.js # 日期时间
├── store.js # 本地存储
├── file.js # 文件处理
├── color.js # 颜色转换
├── theme.js # 主题管理
├── crypto.js # 加密哈希
└── index.js # 统一导出
2. 统一导出 #
javascript
export { getQueryString, getQueryParam, addQueryParam } from './url';
export { getCookie, setCookie, deleteCookie } from './cookie';
export { formater, getTimeSpan, getTimeInfo } from './date';
export { default as store } from './store';
export { formatFileSize, downloadFile, getImageBase64 } from './file';
export { rgb2hex, hex2rgb } from './color';
export { getTheme, setTheme, toggleTheme } from './theme';
export { default as md5 } from './md5';
export { default as md6 } from './md6';
export { deepCopy, deepMerge } from './index';
下一步 #
现在你已经了解了工具函数的基本概念,接下来学习 基础使用,开始使用这些实用的工具函数!
最后更新:2026-04-04