js-toolkits-lucky
v1.0.3
Published
A pure JavaScript toolkit with ES Modules and JSDoc
Downloads
248
Maintainers
Readme
JS Toolkits Lucky
一个纯 JavaScript 开源工具包,提供常用的数字、字符串、数组、对象、函数处理和 Base64 加解密功能。
特性
- 纯 JavaScript 实现,无 TypeScript 依赖
- 使用 ES Modules,支持现代浏览器和 Node.js
- 完整的 JSDoc 注释,提供智能提示
- ESLint 和 Prettier 代码规范
- 模块化设计,按功能分类
- 支持深拷贝、数组去重、数组扁平化等进阶功能
- Git Hooks 自动校验代码质量
安装
npm install js-toolkits-lucky使用方法
引入整个工具包
import * as toolkit from 'js-toolkits-lucky';
// 使用数字工具
toolkit.number.add(1, 2);
toolkit.number.randomInt(1, 100);
// 使用字符串工具
toolkit.string.toUpperCase('hello');
toolkit.string.toCamelCase('hello-world');
// 使用数组工具
toolkit.array.unique([1, 2, 2, 3]);
toolkit.array.flatten([1, [2, [3, 4]]]);
// 使用对象工具
toolkit.object.deepClone({ a: 1, b: { c: 2 } });
toolkit.object.merge({ a: 1 }, { b: 2 });按需引入
// 只引入数字工具
import { add, multiply } from 'js-toolkits-lucky/number';
// 只引入字符串工具
import { toUpperCase, toCamelCase } from 'js-toolkits-lucky/string';API 文档
数字工具 (Number Utilities)
基本运算
add(a, b)- 将两个数字相加subtract(a, b)- 将两个数字相减multiply(a, b)- 将两个数字相乘divide(a, b)- 将两个数字相除
数学运算
abs(num)- 计算数字的绝对值ceil(num)- 向上取整floor(num)- 向下取整round(num)- 四舍五入max(...numbers)- 计算数字的最大值min(...numbers)- 计算数字的最小值pow(base, exponent)- 计算数字的幂sqrt(num)- 计算数字的平方根
随机数
randomInt(min, max)- 生成指定范围内的随机整数
格式化
toFixed(num, decimals)- 将数字格式化为指定小数位数formatThousands(num)- 将数字转换为千分位格式divideWithDecimals(divisor, dividend, decimals)- 数字相除并保留指定小数位数(不够时补零)
divideWithDecimals 示例:
import { divideWithDecimals } from 'js-toolkits-lucky/number';
// 基本使用
divideWithDecimals(10, 3, 2); // "3.33"
divideWithDecimals(10, 3, 4); // "3.3333"
// 补零
divideWithDecimals(10, 4, 2); // "2.50"
divideWithDecimals(10, 5, 3); // "2.000"
// 整数结果
divideWithDecimals(10, 2, 2); // "5.00"特性:
- 自动补零到指定小数位数
- 返回字符串格式,方便显示
- 除数为 0 时抛出错误
- 支持循环小数(自动四舍五入)
类型检查
isInteger(num)- 判断数字是否为整数isFinite(num)- 判断数字是否为有限数isNaN(num)- 判断数字是否为 NaN
其他
percentage(value, total)- 计算数字的百分比
字符串工具 (String Utilities)
大小写转换
toUpperCase(str)- 将字符串转换为大写toLowerCase(str)- 将字符串转换为小写capitalize(str)- 首字母大写toTitleCase(str)- 将字符串转换为标题格式
命名转换
toCamelCase(str)- 将字符串转换为驼峰命名toKebabCase(str)- 将字符串转换为短横线命名toSnakeCase(str)- 将字符串转换为下划线命名
空白处理
trim(str)- 去除字符串两端的空白字符trimStart(str)- 去除字符串左端的空白字符trimEnd(str)- 去除字符串右端的空白字符removeWhitespace(str)- 移除字符串中的所有空白字符
检查
startsWith(str, prefix)- 检查字符串是否以指定前缀开头endsWith(str, suffix)- 检查字符串是否以指定后缀结尾includes(str, searchStr)- 检查字符串是否包含指定子串isEmpty(str)- 检查字符串是否为空isEmail(str)- 检查字符串是否为有效的邮箱地址isPhone(str)- 检查字符串是否为有效的手机号(中国大陆)isUrl(str)- 检查字符串是否为有效的URL
操作
replaceAll(str, search, replacement)- 替换字符串中的所有匹配项repeat(str, count)- 将字符串重复指定次数slice(str, start, end)- 截取字符串reverse(str)- 反转字符串split(str, separator)- 将字符串分割为数组join(arr, separator)- 将数组连接为字符串truncate(str, maxLength, suffix)- 截断字符串到指定长度
工具
length(str)- 获取字符串长度randomString(length)- 生成随机字符串
数组工具 (Array Utilities)
去重
unique(arr)- 数组去重(使用 Set)uniqueByFilter(arr)- 数组去重(使用 filter + indexOf)uniqueByMap(arr)- 数组去重(使用 Map)uniqueByReduce(arr)- 数组去重(使用 reduce)uniqueByKey(arr, key)- 对象数组去重(根据指定属性)uniqueWithNaN(arr)- 数组去重(处理 NaN)uniqueByObject(arr)- 数组去重(使用对象键值对)
扁平化
flatten(arr, depth)- 数组扁平化(使用 flat)flattenByReduce(arr)- 数组扁平化(使用 reduce + concat)flattenDeep(arr)- 数组完全扁平化(无限深度)flattenDepth(arr, depth)- 数组扁平化到指定深度(使用 reduce)flattenByRecursion(arr)- 数组扁平化(使用递归)flattenByWhile(arr)- 数组扁平化(使用 while 循环)flattenByString(arr)- 数组扁平化(使用 toString + split)
分组与分块
groupBy(arr, key)- 数组分组chunk(arr, size)- 数组分块
集合操作
difference(arr1, arr2)- 数组差集intersection(arr1, arr2)- 数组交集union(...arrays)- 数组并集
排序与乱序
uniqueSorted(arr)- 数组去重并排序shuffle(arr)- 数组乱序(Fisher-Yates 洗牌算法)sortByPinyin(arr, key)- 按拼音首字母排序对象数组
sortByPinyin 示例:
import { sortByPinyin } from 'js-toolkits-lucky/array';
const users = [
{ name: '张三', age: 25 },
{ name: '李四', age: 30 },
{ name: '王五', age: 28 },
{ name: '赵六', age: 22 }
];
const sorted = sortByPinyin(users, 'name');
console.log(sorted);
// [
// { name: '李四', age: 30 },
// { name: '王五', age: 28 },
// { name: '张三', age: 25 },
// { name: '赵六', age: 22 }
// ]特性:
- 使用 JavaScript 原生的
localeCompare方法 - 支持中文拼音排序
- 自动处理不同数据类型(转换为字符串)
- 不修改原数组,返回新数组
sort(arr, compareFn)- 数组排序
统计
sum(arr)- 数组求和average(arr)- 数组求平均值max(arr)- 数组求最大值min(arr)- 数组求最小值
查找
indexOf(arr, item, fromIndex)- 数组查找元素索引lastIndexOf(arr, item, fromIndex)- 数组从后往前查找元素索引includes(arr, item)- 数组是否包含指定元素find(arr, predicate)- 数组查找符合条件的第一个元素filter(arr, predicate)- 数组查找符合条件的所有元素
操作
map(arr, mapper)- 数组映射reduce(arr, reducer, initialValue)- 数组归约every(arr, predicate)- 数组判断是否所有元素都符合条件some(arr, predicate)- 数组判断是否有元素符合条件reverse(arr)- 数组反转fill(arr, value, start, end)- 数组填充slice(arr, start, end)- 数组切片concat(arr, ...arrays)- 数组拼接
修改
remove(arr, item)- 数组删除指定元素removeAt(arr, index)- 数组删除指定索引的元素insert(arr, index, ...items)- 数组在指定位置插入元素replace(arr, index, item)- 数组替换指定位置的元素
获取元素
first(arr)- 数组获取第一个元素last(arr)- 数组获取最后一个元素nth(arr, n)- 数组获取第 n 个元素take(arr, n)- 数组获取前 n 个元素takeRight(arr, n)- 数组获取后 n 个元素drop(arr, n)- 数组去掉前 n 个元素dropRight(arr, n)- 数组去掉后 n 个元素
对象工具 (Object Utilities)
拷贝
deepClone(target, hash)- 深拷贝函数(支持循环引用、Date、RegExp、Map、Set、Symbol)shallowClone(target)- 浅拷贝函数
合并
merge(...objects)- 合并多个对象deepMerge(...objects)- 深度合并多个对象
键值操作
keys(obj)- 获取对象的所有键values(obj)- 获取对象的所有值entries(obj)- 获取对象的所有键值对fromEntries(entries)- 从键值对数组创建对象
检查
hasKey(obj, key)- 检查对象是否包含指定的键size(obj)- 获取对象的键数量isEmpty(obj)- 检查对象是否为空
选择
omit(obj, keys)- 删除对象中的指定键pick(obj, keys)- 获取对象中的指定键
对象状态
freeze(obj)- 冻结对象,使其不可修改seal(obj)- 密封对象,防止添加或删除属性isFrozen(obj)- 检查对象是否被冻结isSealed(obj)- 检查对象是否被密封isExtensible(obj)- 检查对象是否可扩展preventExtensions(obj)- 阻止对象扩展
原型操作
getPrototypeOf(obj)- 获取对象的原型setPrototypeOf(obj, prototype)- 设置对象的原型
属性描述符
getOwnPropertyDescriptor(obj, key)- 获取对象的属性描述符getOwnPropertyDescriptors(obj)- 获取对象的所有属性描述符defineProperty(obj, key, descriptor)- 定义对象的属性defineProperties(obj, descriptors)- 定义对象的多个属性
Base64 加解密
encryptBase64(obj, key)- 对象属性 Base64 加密decryptBase64(obj, key)- 对象属性 Base64 解密
关键特性:
环境兼容性:
- 浏览器环境:自动使用
window.btoa()和window.atob() - Node.js 环境:自动使用
Buffer.from()和Buffer.toString() - 自动检测运行环境并使用对应的 API
- 浏览器环境:自动使用
中文支持:
- 浏览器:使用
unescape(encodeURIComponent(str))技巧处理 UTF-8 字符 - Node.js:
Buffer默认支持 UTF-8,无需特殊处理
- 浏览器:使用
非字符串处理:
- 对象/数组:使用
JSON.stringify转换为字符串 - 数字/布尔值:使用
String()转换为字符串
- 对象/数组:使用
无损编码:
- 完美保留空格、缩进、换行符
- 解密后与原始内容完全一致
- 适用于任何代码或文本内容
引用传递:
- 直接修改传入的
obj并返回它 - 不创建新对象,提高性能
- 如需保留原对象,可先使用
{...obj}浅拷贝
- 直接修改传入的
使用示例:
import { encryptBase64, decryptBase64 } from 'js-toolkits-lucky/object';
// 基本使用
const obj = { username: 'admin', password: '123456' };
encryptBase64(obj, 'password');
console.log(obj); // { username: 'admin', password: 'MTIzNDU2' }
decryptBase64(obj, 'password');
console.log(obj); // { username: 'admin', password: '123456' }
// 支持中文
const obj2 = { name: '你好' };
encryptBase64(obj2, 'name');
console.log(obj2); // { name: '5L2g5aW9' }
// 处理代码(保留空格和缩进)
const groovyCode = ` import groovy.json.JsonSlurper;
import cn.hutool.json.JSONObject;
public class JsonSlurperUtil {
public static Object execute(String content){
def jsonSlurper = new JsonSlurper();
def jsonObject = JSONUtil.parseObj(JSONUtil.toJsonStr(jsonSlurper.parseText(content)));
return jsonObject;
}
}`;
const obj3 = { code: groovyCode };
encryptBase64(obj3, 'code');
console.log(obj3.code); // Base64 编码后的字符串
decryptBase64(obj3, 'code');
console.log(obj3.code); // 完全还原原始代码,包括空格和缩进
// 如果不希望修改原对象
const obj4 = { name: 'hello' };
const result = encryptBase64({ ...obj4 }, 'name');
console.log(obj4); // { name: 'hello' } - 原对象不变
console.log(result); // { name: 'aGVsbG8=' } - 新对象被修改函数工具 (Function Utilities)
防抖与节流
debounce(func, delay)- 防抖函数throttle(func, delay)- 节流函数debounceImmediate(func, delay)- 立即执行的防抖函数
防抖函数:
import { debounce } from 'js-toolkits-lucky/function';
// 基本使用
const debouncedFn = debounce(() => {
console.log('执行了');
}, 500);
// 多次调用,只执行最后一次
debouncedFn();
debouncedFn();
debouncedFn();
// 500ms 后输出:执行了
// 实际应用:搜索输入
const handleSearch = debounce((keyword) => {
console.log('搜索:', keyword);
}, 300);
input.addEventListener('input', (e) => {
handleSearch(e.target.value);
});节流函数:
import { throttle } from 'js-toolkits-lucky/function';
// 基本使用
const throttledFn = throttle(() => {
console.log('执行了');
}, 500);
// 多次调用,每 500ms 最多执行一次
throttledFn();
throttledFn();
throttledFn();
throttledFn();
// 立即输出:执行了
// 500ms 后再次输出:执行了
// 实际应用:滚动事件
const handleScroll = throttle(() => {
console.log('滚动位置:', window.scrollY);
}, 100);
window.addEventListener('scroll', handleScroll);立即执行防抖:
import { debounceImmediate } from 'js-toolkits-lucky/function';
const debouncedFn = debounceImmediate(() => {
console.log('执行了');
}, 500);
// 第一次立即执行
debouncedFn(); // 立即输出:执行了
// 后续调用进行防抖
debouncedFn();
debouncedFn();
// 500ms 后输出:执行了区别说明:
- 防抖:多次调用,只在最后一次调用后执行
- 节流:在指定时间内最多执行一次
- 立即防抖:第一次立即执行,后续调用进行防抖
应用场景:
- 防抖:搜索输入、窗口 resize、按钮点击
- 节流:滚动事件、鼠标移动、窗口滚动
- 立即防抖:表单提交、按钮点击(需要立即响应)
开发
安装依赖
npm install代码检查
npm run lint自动修复代码问题
npm run lint:fix代码格式化
npm run format检查代码格式
npm run format:checkGit Hooks
项目已配置 Husky 和 lint-staged,在提交代码时会自动执行以下检查:
- 对暂存的文件运行 ESLint 检查并自动修复问题
- 对暂存的文件运行 Prettier 格式化
如果代码不符合规范,提交将被阻止。确保在提交前代码已经通过所有检查。
项目结构
js-toolkits-lucky/
├── src/
│ ├── number/ # 数字处理工具
│ │ └── index.js
│ ├── string/ # 字符串处理工具
│ │ └── index.js
│ ├── array/ # 数组处理工具
│ │ └── index.js
│ ├── object/ # 对象处理工具
│ │ └── index.js
│ └── index.js # 主入口文件
├── tests/ # 测试文件
├── docs/ # 文档
├── .eslintrc.js # ESLint 配置
├── .prettierrc # Prettier 配置
├── .gitignore # Git 忽略规则
└── package.json # 项目配置贡献
欢迎提交 Issue 和 Pull Request!
发布到 npm
准备工作
- 更新 package.json 中的仓库信息
- 将
repository.url替换为你的 GitHub 仓库地址 - 将
bugs.url替换为你的 Issues 地址 - 将
homepage替换为你的项目主页
- 将
发布步骤
注意:如果你默认登录的是公司的私有 npm 仓库,需要先切换到 npm 公共仓库。
方法 1:使用 .npmrc 文件(推荐)
项目已包含 .npmrc 文件,自动使用 npm 公共仓库:
registry=https://registry.npmjs.org/方法 2:临时指定仓库
npm publish --registry https://registry.npmjs.org/方法 3:配置 npm 用户
# 登录 npm 公共仓库
npm login --registry=https://registry.npmjs.org/
# 发布时指定用户
npm publish --registry=https://registry.npmjs.org/方法 4:使用 npm 配置
# 查看当前配置
npm config list
# 设置公共仓库
npm config set registry https://registry.npmjs.org/
# 发布
npm publish- 登录 npm 账号
npm login
重要:如果你的 npm 账户启用了双因素认证(2FA),需要使用 Access Token 登录。
创建 Access Token
- 访问 npmjs.com 并登录
- 点击右上角头像 → Access Tokens
- 点击 Generate New Token
- 选择 Automation 类型(用于自动化发布)
- 设置 Token 名称(如:
js-toolkits-lucky-publish) - 选择权限:
- ✅ Automation - 用于 CI/CD 和自动化
- ✅ Publish - 发布包权限
- ✅ Bypass 2FA - 必须勾选这个选项!(绕过双因素认证)
- 点击 Generate Token 生成令牌
- 重要:复制生成的 Token(只显示一次,之后无法再次查看)
注意:如果 Token 没有勾选 "Bypass 2FA",发布时会收到 403 错误。
方法 5:强制指定 registry(解决公司代理问题)
如果你的 npm 被公司代理覆盖,可以在发布时强制指定官方 registry:
# 强制使用 npm 官方仓库
npm publish --registry https://registry.npmjs.org/
# 结合 Token 使用
npm publish --registry https://registry.npmjs.org/ --auth-token your_token_here方法 6:临时清除公司代理配置
# 临时清除代理配置
npm config delete registry
# 设置为官方仓库
npm config set registry https://registry.npmjs.org/
# 发布
npm publish注意:这些方法只在当前会话有效,重启终端后会恢复公司配置。
使用 Token 的多种方法
方法 1:使用环境变量(推荐)
# Windows PowerShell
$env:NPM_TOKEN="your_token_here"
# Linux/Mac
export NPM_TOKEN="your_token_here"
# 发布时会自动使用
npm publish方法 2:使用 npm config
# 设置 token
npm config set //registry.npmjs.org/:_authToken your_token_here
# 发布
npm publish方法 3:发布时指定 token
# ⚠️ 注意:使用 --auth-token(双横线),不是 --token
npm publish --auth-token your_token_here方法 4:使用 .npmrc 文件
项目已包含 .npmrc.example 文件,复制并重命名为 .npmrc:
cp .npmrc.example .npmrc
# 然后编辑 .npmrc,将 your_token_here 替换为实际的 Token方法 5:浏览器登录(当前遇到的问题)
npm login --registry=https://registry.npmjs.org/
# 会打开浏览器,按提示完成登录检查包名是否可用
npm view js-toolkits-lucky如果显示 404,说明包名可用
发布包
npm publish发布特定版本
npm publish --tag beta
更新版本
修改 package.json 中的 version 字段,然后重新发布:
# 1. 更新版本号(例如:1.0.0 -> 1.0.1)
# 2. 提交代码
git add .
git commit -m "chore: bump version to 1.0.1"
# 3. 推送到 GitHub
git push
# 4. 发布到 npm
npm publish注意事项
- 确保包名唯一且未被占用
- 首次发布需要验证邮箱
- 每次发布都需要新的版本号
- 发布前运行
npm run lint确保代码质量 - 本项目为纯 JavaScript ES Modules,无需构建步骤,直接发布源码
许可证
MIT
