npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

l-js-fn

v3.4.0

Published

轻量级 JavaScript 工具函数库,支持模块化导入和 Tree-shaking

Readme

l-js-fn

整理了常用的 JavaScript 方法,轻量级、零依赖、TypeScript 支持

npm version downloads license

✨ 特性

  • 🚀 轻量级 - 零依赖,打包体积小
  • 📦 模块化 - 支持按需导入,减少包体积
  • 🔒 TypeScript - 完整的类型定义
  • 🌐 双模块格式 - 同时支持 ESM 和 CJS
  • 🎨 Tree-shaking - 完整支持 Tree-shaking,只打包用到的代码
  • 💪 工具齐全 - 涵盖数组、对象、字符串、日期、URL、正则等常用操作
  • 🔧 高级功能 - WebSocket 管理、轮询、IPC 通信等

📦 安装

npm install l-js-fn
# 或
yarn add l-js-fn
# 或
pnpm add l-js-fn

🚀 快速开始

导入主包(包含所有工具函数)

import { isArray, dateFormat, isEmpty } from 'l-js-fn';

// 类型判断
isArray([1, 2, 3]); // true

// 日期格式化
dateFormat(new Date(), 'yyyy-MM-dd HH:mm:ss'); // "2024-01-01 12:00:00"

// 空值检查
isEmpty(''); // true
isEmpty(null); // true

按需导入(推荐)

只导入你需要的模块,减少打包体积:

// 浏览器对象模型方法
import { scrollTop, copyToClipboard, launchFullscreen } from 'l-js-fn/bom';

// 轮询工具类
import { Polling } from 'l-js-fn/polling';

// WebSocket 管理类
import { WebSocketManager } from 'l-js-fn/ws';

// 正则表达式常量
import { REGEXP } from 'l-js-fn/regex';

// 配置常量
import { DATE_FORMAT, HTTP_STATUS } from 'l-js-fn/config';

// IPC 通信
import { H5Bridge, IframeBridge } from 'l-js-fn/ipc';

// 编码/解码
import { escapeHTML, base64Encode } from 'l-js-fn/encode';

// 文件处理
import { formatFileSize, isImage } from 'l-js-fn/file';

📚 API 文档

主包工具函数

类型判断 (is-kit)

import {
  isEmpty,
  isNotEmpty,
  isObject,
  isArray,
  isString,
  isEmail,
  isURL,
  isIdCard,
  isPhoneNumber,
  isEqual,
  validateParams
} from 'l-js-fn';

// 空值检查
isEmpty(''); // true
isEmpty([]); // true
isEmpty({}); // true

// 邮箱验证
isEmail('[email protected]'); // true

// 手机号验证(中国大陆)
isPhoneNumber('13800138000'); // true

// 身份证验证
isIdCard('110101199001011234'); // true

// 深度比较
isEqual({ a: 1 }, { a: 1 }); // true

// 参数校验
validateParams(['name', 'age'], { name: 'John', age: 20 }); // null
validateParams(['name'], { age: 20 }); // 'name'

数组操作 (array-kit)

import {
  arrayDelEl,
  arrayDelToIndex,
  arrayFill,
  arrayUnique,
  arrayPaginate,
  arraySplitToGroups,
  moveElement,
  groupBy,
  sample,
  sampleSize
} from 'l-js-fn';

// 删除元素
arrayDelEl([1, 2, 3, 2], 2); // [1, 3]

// 根据索引删除
arrayDelToIndex([1, 2, 3], 1); // [1, 3]

// 数组补充到指定长度
arrayFill([1, 2], 5, 0); // [1, 2, 0, 0, 0]

// 数组去重
arrayUnique([1, 2, 2, 3]); // [1, 2, 3]

// 数组分页
arrayPaginate([1, 2, 3, 4, 5], 2, 2); // [3, 4]

// 数组分组
arraySplitToGroups([1, 2, 3, 4, 5], 2);
// { 1: [1, 2], 2: [3, 4], 3: [5] }

// 移动数组元素
moveElement([1, 2, 3], 1, 'up'); // 移动索引1的元素向上

// 按字段分组对象数组
groupBy([
  { name: 'Alice', age: 25 },
  { name: 'Bob', age: 25 },
  { name: 'Charlie', age: 30 }
], 'age');
// { 25: [{ name: 'Alice', age: 25 }, { name: 'Bob', age: 25 }], 30: [{ name: 'Charlie', age: 30 }] }

// 随机取一个元素
sample([1, 2, 3, 4, 5]); // 3(随机)

// 随机取 n 个元素
sampleSize([1, 2, 3, 4, 5], 2); // [2, 5](随机)

字符串处理 (string-kit)

import {
  desensitization,
  trim,
  getMobile,
  getUuid,
  indexToLabel
} from 'l-js-fn';

// 字符串脱敏
desensitization('13800138000', 3, 4); // "138****8000"

// 去除空格
trim('  hello  '); // "hello"
trim('  hello  ', 'all'); // "hello"

// 生成随机手机号
getMobile(); // "13800138000"

// 生成 UUID
getUuid(); // "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"

// 索引转标签
indexToLabel(0, 'upper'); // "A"
indexToLabel(1, 'lower'); // "b"
indexToLabel(0, 'chinese'); // "一"

对象操作 (object-kit)

import {
  objMerge,
  objFilterProp,
  objFilterNull,
  jsonToFormData,
  formDataToObject
} from 'l-js-fn';

// 对象合并
objMerge({ a: 1 }, { b: 2 }); // { a: 1, b: 2 }

// 过滤属性
objFilterProp({ a: 1, b: 2, c: 3 }, ['b']); // { a: 1, c: 3 }

// 过滤空值
objFilterNull({ a: 1, b: null, c: undefined }); // { a: 1 }

// JSON 转 FormData
jsonToFormData({ name: 'John', age: 20 }); // FormData

// FormData 转 JSON
formDataToObject(formData); // { name: 'John', age: 20 }

日期处理 (date-kit)

import {
  dateFormat,
  dateSecond,
  diffDays,
  formatPassTime,
  monthDays,
  getTimeDiff
} from 'l-js-fn';

// 日期格式化
dateFormat(new Date()); // "2024-01-01 12:00:00"
dateFormat(new Date(), 'yyyy-MM-dd'); // "2024-01-01"

// 秒数转时间
dateSecond(3661); // "01:01:01"

// 计算天数差
diffDays('2024-01-01', '2024-01-03'); // 2

// 格式化过去时间
formatPassTime('2024-01-01 12:00:00'); // "3天前"

// 获取当月天数
monthDays('2024-02-01'); // 29

// 时间差计算
getTimeDiff('2024-01-01', '2024-01-02'); // 86400000

数字处理 (number-kit)

import {
  formatNumber,
  toPercent,
  random,
  getUniqueRandomIndexes
} from 'l-js-fn';

// 数字格式化
formatNumber(1234567); // "1,234,567"
formatNumber(1234567, true); // "123万"

// 转百分比
toPercent(0.5332); // "53.32%"

// 生成随机数
random(10); // 0-10 之间的随机整数
random(1, 10); // 1-10 之间的随机整数
random(1, 10, { float: true }); // 1-10 之间的随机浮点数

// 生成不重复随机索引
getUniqueRandomIndexes(10, 3); // [0, 5, 8]

URL 处理 (url-kit)

import {
  getUrlParams,
  getUrlParam,
  appendUrlParam,
  transUrlParams,
  getFileInfoToUrl
} from 'l-js-fn';

// 解析 URL 参数
getUrlParams('https://example.com?id=1&name=John');
// { id: '1', name: 'John' }

// 获取单个参数
getUrlParam('https://example.com?id=1', 'id'); // '1'

// 添加 URL 参数
appendUrlParam('https://example.com', 'id', 1);
// "https://example.com?id=1"

// 对象转 URL 参数
transUrlParams({ id: 1, name: 'John' }); // "id=1&name=John"

// 从 URL 获取文件信息
getFileInfoToUrl('https://example.com/file.txt');
// { fileName: 'file.txt', extension: '.txt' }

通用工具 (common)

import {
  sleep,
  debounce,
  throttle,
  getType,
  deepClone,
  getDevice,
  imageToBase64
} from 'l-js-fn';

// 睡眠函数
await sleep(1000); // 延迟 1 秒

// 防抖
const debouncedFn = debounce(() => {
  console.log('执行');
}, 300);

// 节流
const throttledFn = throttle(() => {
  console.log('执行');
}, 300);

// 获取类型
getType([1, 2, 3]); // "array"
getType(new Date()); // "date"

// 深拷贝
deepClone({ a: { b: 1 } }); // { a: { b: 1 } }

// 获取设备类型
getDevice(); // "ios" | "android" | "windows" | "macos" | ...

// 图片转 Base64
const result = await imageToBase64('https://example.com/image.png');

浏览器对象模型 (bom)

import {
  scrollTop,
  scrollToBottom,
  getScrollPosition,
  setScrollPosition,
  launchFullscreen,
  exitFullscreen,
  copyToClipboard,
  setCookie,
  getCookie,
  removeCookie,
  hasCookie,
  getAllCookies
} from 'l-js-fn/bom';

// 平滑滚动到顶部
scrollTop();

// 滚动到底部
scrollToBottom();

// 获取滚动位置
getScrollPosition(); // { x: 0, y: 100 }

// 设置滚动位置
setScrollPosition({ x: 0, y: 100 }, true);

// 进入全屏
await launchFullscreen(document.documentElement);

// 退出全屏
await exitFullscreen();

// 复制到剪贴板
await copyToClipboard('要复制的文本');

// Cookie 操作
setCookie('token', 'abc123', { expires: 30, secure: true }); // 设置 Cookie,30 天后过期
getCookie('token'); // 'abc123'
hasCookie('token'); // true
removeCookie('token'); // 删除 Cookie
getAllCookies(); // { token: 'abc123', user: 'john' }

本地存储 (storage)

import {
  setStorage,
  getStorage,
  removeStorage,
  clearStorage,
  clearExpiredStorage,
  setSession,
  getSession,
  removeSession
} from 'l-js-fn/storage';

// localStorage 操作(支持过期时间)
setStorage('user', { name: 'John', age: 20 });
setStorage('token', 'abc123', { expire: 3600 }); // 1 小时后过期
getStorage('user'); // { name: 'John', age: 20 }
getStorage('token'); // 'abc123'(未过期)或 null(已过期)
removeStorage('user');
clearStorage();
clearExpiredStorage(); // 清理所有已过期的数据

// sessionStorage 操作
setSession('tabData', { id: 1, name: 'test' });
getSession('tabData'); // { id: 1, name: 'test' }
removeSession('tabData');

WebSocket 管理 (ws)

import { WebSocketManager } from 'l-js-fn/ws';

const ws = new WebSocketManager(
  'ws://localhost:8080',
  (message) => console.log('收到消息:', message),
  (error) => console.error('错误:', error)
);

// 发送消息
ws.sendWebSocketMessage({ type: 'ping', data: 'hello' });

// 检查连接并发送消息
ws.checkConnection({ type: 'heartbeat' }, 10000);

// 重新连接
ws.reconnect(5000);

// 关闭连接
ws.close();

轮询工具 (polling)

import { Polling } from 'l-js-fn/polling';

const polling = new Polling();

// 启动轮询
polling.start(
  async () => {
    const response = await fetch('https://api.example.com/data');
    return response.json();
  },
  1000, // 间隔 1 秒
  true // 立即执行
);

// 停止轮询
polling.stop();

// 检查是否正在运行
polling.running; // true

正则表达式 (regex)

import { REGEXP } from 'l-js-fn/regex';

// 手机号验证
REGEXP.PHONE.test('13800138000'); // true

// 邮箱验证
REGEXP.EMAIL.test('[email protected]'); // true

// URL 验证
REGEXP.URL.test('https://example.com'); // true

// 身份证验证
REGEXP.ID_CARD.test('110101199001011234'); // true

// 中文验证
REGEXP.CHINESE.test('中文'); // true

// 金额验证
REGEXP.MONEY.test('123.45'); // true

配置常量 (config)

import { DATE_FORMAT, HTTP_STATUS } from 'l-js-fn/config';

// 日期格式
DATE_FORMAT.FULL; // "yyyy-MM-dd HH:mm:ss"
DATE_FORMAT.DATE; // "yyyy-MM-dd"
DATE_FORMAT.TIME; // "HH:mm:ss"

// HTTP 状态码
HTTP_STATUS.OK; // 200
HTTP_STATUS.UNAUTHORIZED; // 401
HTTP_STATUS.NOT_FOUND; // 404

IPC 通信 (ipc)

import { H5Bridge, IframeBridge } from 'l-js-fn/ipc';

// H5 与原生通信
const h5Bridge = new H5Bridge();

// Iframe 通信
const iframeBridge = new IframeBridge('https://example.com');

编码/解码 (encode)

import {
  base64Encode,
  base64Decode,
  escapeHTML,
  unescapeHTML,
  urlEncode,
  urlDecode,
  querystringify,
  parseQueryString
} from 'l-js-fn/encode';

// Base64 编码/解码(支持 Unicode)
base64Encode('Hello World'); // 'SGVsbG8gV29ybGQ='
base64Encode('你好'); // '5L2g5aW9'
base64Decode('SGVsbG8gV29ybGQ='); // 'Hello World'

// HTML 转义/反转义(防 XSS 攻击)
escapeHTML('<script>alert("XSS")</script>');
// '&lt;script&gt;alert(&quot;XSS&quot;)&lt;&#x2F;script&gt;'
unescapeHTML('&lt;div&gt;'); // '<div>'

// URL 编码/解码
urlEncode('Hello World!'); // 'Hello%20World!'
urlDecode('Hello%20World'); // 'Hello World'

// 查询字符串转换
querystringify({ name: 'John', age: 20 }); // 'name=John&age=20'
querystringify({ a: [1, 2, 3] }); // 'a=1&a=2&a=3'
parseQueryString('name=John&age=20'); // { name: 'John', age: '20' }
parseQueryString('?a=1&a=2'); // { a: ['1', '2'] }

文件处理 (file)

import {
  formatFileSize,
  getExtension,
  getFileName,
  downloadFile,
  readAsText,
  readAsDataURL,
  readAsArrayBuffer,
  isImage,
  isVideo,
  isAudio,
  isPDF,
  FileSizeUnit
} from 'l-js-fn/file';

// 格式化文件大小
formatFileSize(1024); // { formatted: '1 KB', value: 1, unit: 'KB' }
formatFileSize(1536000); // { formatted: '1.46 MB', value: 1.46, unit: 'MB' }
formatFileSize(1024, { precision: 0 }); // { formatted: '1 KB', value: 1, unit: 'KB' }
formatFileSize(1000, { base: 1000 }); // { formatted: '1 KB', value: 1, unit: 'KB' }

// 文件名处理
getExtension('image.png'); // '.png'
getExtension('/path/to/file.txt'); // '.txt'
getFileName('/path/to/image.png'); // 'image'
getFileName('document.pdf'); // 'document'

// 浏览器下载文件
const blob = new Blob(['Hello World'], { type: 'text/plain' });
downloadFile(blob, 'hello.txt');

// 读取文件内容
const file = new File(['content'], 'test.txt');
await readAsText(file); // 'content'
await readAsDataURL(file); // 'data:text/plain;base64,...'
await readAsArrayBuffer(file); // ArrayBuffer

// 文件类型判断
isImage('photo.jpg'); // true
isVideo('movie.mp4'); // true
isAudio('music.mp3'); // true
isPDF('document.pdf'); // true

🌐 浏览器兼容性

  • Chrome >= 90
  • Firefox >= 88
  • Safari >= 14
  • Edge >= 90

📦 模块化导入

本项目支持多种导入方式:

// 导入主包
import { isArray } from 'l-js-fn';

// 按需导入子模块
import { scrollTop } from 'l-js-fn/bom';
import { Polling } from 'l-js-fn/polling';
import { WebSocketManager } from 'l-js-fn/ws';
import { escapeHTML } from 'l-js-fn/encode';
import { formatFileSize } from 'l-js-fn/file';

// CommonJS 导入
const { isArray } = require('l-js-fn');
const { scrollTop } = require('l-js-fn/bom');
const { escapeHTML } = require('l-js-fn/encode');