JavaScript 库
JavaScript 库是预先编写好的代码集合,提供了特定功能的封装,可以简化开发过程、提高开发效率。在现代 JavaScript 开发中,合理使用库可以大大减少重复工作,提升代码质量。在本章节中,我们将学习 JavaScript 中常用的库及其使用方法。
什么是 JavaScript 库
JavaScript 库是一组预先编写好的 JavaScript 代码,封装了特定功能,供开发者在项目中重复使用。库通常解决特定领域的问题,如 DOM 操作、动画效果、数据处理等。
库的特点
- 功能专一:专注于解决特定问题
- 可重用性:可以在多个项目中使用
- 封装性:隐藏实现细节,提供简洁接口
- 标准化:遵循行业标准和最佳实践
- 社区支持:通常有活跃的社区维护
常用 JavaScript 库
1. Lodash - 实用工具库
Lodash 是一个现代化的 JavaScript 实用工具库,提供了对数组、对象、字符串等数据类型的处理方法。
javascript
// 安装: npm install lodash
// 导入
const _ = require('lodash');
// 数组操作
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
// 分块
console.log(_.chunk(numbers, 3));
// [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
// 去重
const duplicates = [1, 2, 2, 3, 3, 4, 5, 5];
console.log(_.uniq(duplicates)); // [1, 2, 3, 4, 5]
// 差集
const array1 = [1, 2, 3];
const array2 = [2, 3, 4];
console.log(_.difference(array1, array2)); // [1]
// 交集
console.log(_.intersection(array1, array2)); // [2, 3]
// 并集
console.log(_.union(array1, array2)); // [1, 2, 3, 4]
// 对象操作
const users = [
{ name: "张三", age: 25, active: true },
{ name: "李四", age: 30, active: false },
{ name: "王五", age: 35, active: true }
];
// 过滤
console.log(_.filter(users, { active: true }));
// [{ name: "张三", age: 25, active: true }, { name: "王五", age: 35, active: true }]
// 查找
console.log(_.find(users, { age: 30 })); // { name: "李四", age: 30, active: false }
// 分组
console.log(_.groupBy(users, "active"));
// {
// true: [{ name: "张三", age: 25, active: true }, { name: "王五", age: 35, active: true }],
// false: [{ name: "李四", age: 30, active: false }]
// }
// 排序
console.log(_.orderBy(users, ["age"], ["desc"]));
// 深度克隆
const original = {
name: "张三",
profile: {
age: 25,
hobbies: ["读书", "游泳"]
}
};
const cloned = _.cloneDeep(original);
cloned.profile.age = 26;
console.log(original.profile.age); // 25
console.log(cloned.profile.age); // 26
// 防抖
const debouncedFunction = _.debounce(() => {
console.log("防抖函数执行");
}, 300);
// 节流
const throttledFunction = _.throttle(() => {
console.log("节流函数执行");
}, 1000);
// 字符串操作
console.log(_.camelCase("hello world")); // "helloWorld"
console.log(_.kebabCase("hello world")); // "hello-world"
console.log(_.startCase("hello world")); // "Hello World"
console.log(_.capitalize("hello world")); // "Hello world"
// 函数组合
const add = (x, y) => x + y;
const multiply = (x, y) => x * y;
const addAndMultiply = _.flow([add, _.curry(multiply)(2)]);
console.log(addAndMultiply(3, 4)); // 14 (3+4=7, 7*2=14)2. Moment.js - 日期处理库
Moment.js 是一个强大的日期处理库,简化了 JavaScript 中的日期操作。
javascript
// 注意:Moment.js 现在处于维护模式,推荐使用 Day.js 或原生 Date 对象
// 安装: npm install moment
const moment = require('moment');
// 创建日期
const now = moment();
const specificDate = moment("2024-01-15");
const fromString = moment("2024-01-15 10:30:00");
// 格式化日期
console.log(now.format("YYYY-MM-DD")); // "2024-01-15"
console.log(now.format("YYYY年MM月DD日 HH:mm:ss")); // "2024年01月15日 10:30:00"
// 日期计算
console.log(now.add(7, "days").format("YYYY-MM-DD")); // 7天后
console.log(now.subtract(1, "months").format("YYYY-MM-DD")); // 1个月前
console.log(now.startOf("month").format("YYYY-MM-DD")); // 月初
console.log(now.endOf("month").format("YYYY-MM-DD")); // 月末
// 日期比较
const date1 = moment("2024-01-15");
const date2 = moment("2024-01-20");
console.log(date1.isBefore(date2)); // true
console.log(date1.isAfter(date2)); // false
console.log(date1.isSame(date2, "year")); // true
// 日期差值
console.log(date2.diff(date1, "days")); // 5
console.log(date2.diff(date1, "hours")); // 120
// 相对时间
console.log(moment().subtract(1, "hour").fromNow()); // "1小时前"
console.log(moment().subtract(1, "day").fromNow()); // "1天前"
console.log(moment().add(3, "days").fromNow()); // "3天后"
// 时区处理
// 需要安装 moment-timezone
// const moment = require('moment-timezone');
// console.log(moment().tz("Asia/Shanghai").format());
// console.log(moment().tz("America/New_York").format());3. Axios - HTTP 客户端库
Axios 是一个基于 Promise 的 HTTP 客户端,用于浏览器和 Node.js。
javascript
// 安装: npm install axios
const axios = require('axios');
// 基本 GET 请求
axios.get('https://api.github.com/users/octocat')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});
// 带参数的 GET 请求
axios.get('https://api.github.com/search/repositories', {
params: {
q: 'javascript',
sort: 'stars',
order: 'desc'
}
}).then(response => {
console.log(response.data.items);
});
// POST 请求
axios.post('https://jsonplaceholder.typicode.com/posts', {
title: 'foo',
body: 'bar',
userId: 1
}).then(response => {
console.log(response.data);
});
// 并发请求
Promise.all([
axios.get('https://api.github.com/users/octocat'),
axios.get('https://api.github.com/users/torvalds')
]).then(([octocat, torvalds]) => {
console.log('Octocat:', octocat.data.name);
console.log('Torvalds:', torvalds.data.name);
});
// 创建实例
const api = axios.create({
baseURL: 'https://api.example.com',
timeout: 5000,
headers: {
'Authorization': 'Bearer your-token',
'Content-Type': 'application/json'
}
});
// 请求拦截器
api.interceptors.request.use(
config => {
console.log('发送请求:', config.url);
return config;
},
error => {
return Promise.reject(error);
}
);
// 响应拦截器
api.interceptors.response.use(
response => {
console.log('收到响应:', response.status);
return response;
},
error => {
if (error.response && error.response.status === 401) {
// 处理未授权错误
console.log('未授权,请重新登录');
}
return Promise.reject(error);
}
);
// 使用实例
api.get('/users')
.then(response => {
console.log(response.data);
})
.catch(error => {
console.error(error);
});4. D3.js - 数据可视化库
D3.js 是一个强大的数据可视化库,用于创建动态、交互式的数据图表。
html
<!DOCTYPE html>
<html>
<head>
<title>D3.js 示例</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
<style>
.bar {
fill: steelblue;
}
.bar:hover {
fill: orange;
}
.axis {
font: 12px sans-serif;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
</style>
</head>
<body>
<div id="chart"></div>
<script>
// 准备数据
const data = [
{ name: "苹果", value: 30 },
{ name: "香蕉", value: 20 },
{ name: "橙子", value: 25 },
{ name: "葡萄", value: 15 },
{ name: "草莓", value: 10 }
];
// 设置图表尺寸和边距
const margin = { top: 20, right: 30, bottom: 40, left: 40 };
const width = 500 - margin.left - margin.right;
const height = 300 - margin.top - margin.bottom;
// 创建 SVG 容器
const svg = d3.select("#chart")
.append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", `translate(${margin.left},${margin.top})`);
// 设置比例尺
const x = d3.scaleBand()
.domain(data.map(d => d.name))
.range([0, width])
.padding(0.1);
const y = d3.scaleLinear()
.domain([0, d3.max(data, d => d.value)])
.range([height, 0]);
// 创建条形
svg.selectAll(".bar")
.data(data)
.enter()
.append("rect")
.attr("class", "bar")
.attr("x", d => x(d.name))
.attr("width", x.bandwidth())
.attr("y", d => y(d.value))
.attr("height", d => height - y(d.value));
// 添加 X 轴
svg.append("g")
.attr("class", "axis")
.attr("transform", `translate(0,${height})`)
.call(d3.axisBottom(x));
// 添加 Y 轴
svg.append("g")
.attr("class", "axis")
.call(d3.axisLeft(y));
// 添加标题
svg.append("text")
.attr("x", width / 2)
.attr("y", 0 - (margin.top / 2))
.attr("text-anchor", "middle")
.style("font-size", "16px")
.text("水果销售数据");
</script>
</body>
</html>5. Three.js - 3D 图形库
Three.js 是一个基于 WebGL 的 3D 图形库,用于在浏览器中创建和显示 3D 内容。
html
<!DOCTYPE html>
<html>
<head>
<title>Three.js 示例</title>
<style>
body { margin: 0; }
canvas { display: block; }
</style>
</head>
<body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<script>
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 创建立方体
const geometry = new THREE.BoxGeometry();
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 创建光源
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(1, 1, 1).normalize();
scene.add(light);
// 动画循环
function animate() {
requestAnimationFrame(animate);
// 旋转立方体
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
// 窗口大小调整
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
</script>
</body>
</html>库的选择和使用
选择标准
javascript
// 评估库的标准
const libraryEvaluationCriteria = {
// 1. 功能性
features: [
"是否满足项目需求",
"功能是否完整",
"扩展性如何"
],
// 2. 性能
performance: [
"加载速度",
"运行效率",
"内存占用"
],
// 3. 稳定性
stability: [
"版本更新频率",
"bug 修复速度",
"长期维护情况"
],
// 4. 社区支持
community: [
"文档质量",
"社区活跃度",
"第三方资源"
],
// 5. 学习成本
learningCurve: [
"API 设计是否直观",
"文档是否清晰",
"示例是否丰富"
],
// 6. 兼容性
compatibility: [
"浏览器支持",
"与其他库的兼容性",
"移动端支持"
],
// 7. 大小
size: [
"文件大小",
"是否支持按需加载",
"Tree shaking 支持"
]
};
// 库比较示例
const libraryComparison = {
lodash: {
size: "70KB (gzip)",
features: "全面的工具函数",
performance: "优秀",
stability: "非常稳定",
community: "活跃"
},
underscore: {
size: "17KB (gzip)",
features: "基础工具函数",
performance: "良好",
stability: "稳定",
community: "较活跃"
},
ramda: {
size: "12KB (gzip)",
features: "函数式编程",
performance: "良好",
stability: "稳定",
community: "中等"
}
};按需加载
javascript
// Lodash 按需加载
// 安装: npm install lodash
const chunk = require('lodash/chunk');
const uniq = require('lodash/uniq');
const debounce = require('lodash/debounce');
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
console.log(chunk(numbers, 3)); // [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10]]
console.log(uniq([1, 2, 2, 3, 3, 4])); // [1, 2, 3, 4]
// 防抖函数
const debouncedSearch = debounce((query) => {
console.log("搜索:", query);
}, 300);
// D3.js 按需加载
// 安装: npm install d3-selection d3-scale d3-axis
// import { select } from 'd3-selection';
// import { scaleLinear, scaleBand } from 'd3-scale';
// import { axisBottom, axisLeft } from 'd3-axis';自定义工具库
创建自己的库
javascript
// utils.js - 自定义工具库
class CustomUtils {
// 数组工具
static array = {
// 数组分块
chunk(array, size) {
const chunks = [];
for (let i = 0; i < array.length; i += size) {
chunks.push(array.slice(i, i + size));
}
return chunks;
},
// 数组去重
unique(array) {
return [...new Set(array)];
},
// 数组差集
difference(array, ...values) {
const flatValues = values.flat();
return array.filter(item => !flatValues.includes(item));
},
// 数组交集
intersection(array, ...values) {
const flatValues = values.flat();
return array.filter(item => flatValues.includes(item));
},
// 数组随机排序
shuffle(array) {
const result = [...array];
for (let i = result.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[result[i], result[j]] = [result[j], result[i]];
}
return result;
}
};
// 对象工具
static object = {
// 深度克隆
deepClone(obj) {
if (obj === null || typeof obj !== "object") return obj;
if (obj instanceof Date) return new Date(obj);
if (obj instanceof Array) return obj.map(item => this.deepClone(item));
if (obj instanceof Object) {
const clonedObj = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
clonedObj[key] = this.deepClone(obj[key]);
}
}
return clonedObj;
}
},
// 对象映射
map(obj, fn) {
const result = {};
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
result[key] = fn(obj[key], key);
}
}
return result;
},
// 对象过滤
filter(obj, fn) {
const result = {};
for (const key in obj) {
if (obj.hasOwnProperty(key) && fn(obj[key], key)) {
result[key] = obj[key];
}
}
return result;
},
// 对象合并
merge(target, ...sources) {
sources.forEach(source => {
for (const key in source) {
if (source.hasOwnProperty(key)) {
if (typeof source[key] === "object" && source[key] !== null && !Array.isArray(source[key])) {
if (!target[key]) target[key] = {};
this.merge(target[key], source[key]);
} else {
target[key] = source[key];
}
}
}
});
return target;
}
};
// 字符串工具
static string = {
// 驼峰命名
camelCase(str) {
return str.replace(/[-_\s]+(.)?/g, (_, c) => c ? c.toUpperCase() : '');
},
// 短横线命名
kebabCase(str) {
return str.replace(/([A-Z])/g, '-$1')
.replace(/[-_\s]+/g, '-')
.toLowerCase();
},
// 首字母大写
capitalize(str) {
return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase();
},
// 格式化字符串
format(str, ...args) {
return str.replace(/{(\d+)}/g, (match, index) => {
return typeof args[index] !== 'undefined' ? args[index] : match;
});
}
};
// 数字工具
static number = {
// 精确加法
add(a, b, precision = 10) {
return parseFloat((a + b).toFixed(precision));
},
// 精确减法
subtract(a, b, precision = 10) {
return parseFloat((a - b).toFixed(precision));
},
// 精确乘法
multiply(a, b, precision = 10) {
return parseFloat((a * b).toFixed(precision));
},
// 精确除法
divide(a, b, precision = 10) {
if (b === 0) throw new Error("除数不能为零");
return parseFloat((a / b).toFixed(precision));
},
// 格式化数字
format(num, options = {}) {
const {
decimals = 2,
thousandSeparator = ",",
decimalSeparator = "."
} = options;
const fixed = num.toFixed(decimals);
const [integer, decimal] = fixed.split(".");
const formattedInteger = integer.replace(
/\B(?=(\d{3})+(?!\d))/g,
thousandSeparator
);
return decimal
? formattedInteger + decimalSeparator + decimal
: formattedInteger;
}
};
// 函数工具
static function = {
// 防抖
debounce(func, wait, immediate = false) {
let timeout;
return function executedFunction(...args) {
const later = () => {
timeout = null;
if (!immediate) func.apply(this, args);
};
const callNow = immediate && !timeout;
clearTimeout(timeout);
timeout = setTimeout(later, wait);
if (callNow) func.apply(this, args);
};
},
// 节流
throttle(func, limit) {
let inThrottle;
return function() {
const args = arguments;
const context = this;
if (!inThrottle) {
func.apply(context, args);
inThrottle = true;
setTimeout(() => inThrottle = false, limit);
}
};
},
// 记忆化
memoize(func, resolver) {
const memoized = function(...args) {
const key = resolver ? resolver.apply(this, args) : args[0];
if (memoized.cache.has(key)) {
return memoized.cache.get(key);
}
const result = func.apply(this, args);
memoized.cache.set(key, result);
return result;
};
memoized.cache = new Map();
return memoized;
}
};
// 日期工具
static date = {
// 格式化日期
format(date, format = "YYYY-MM-DD") {
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");
const hours = String(d.getHours()).padStart(2, "0");
const minutes = String(d.getMinutes()).padStart(2, "0");
const seconds = String(d.getSeconds()).padStart(2, "0");
return format
.replace("YYYY", year)
.replace("MM", month)
.replace("DD", day)
.replace("HH", hours)
.replace("mm", minutes)
.replace("ss", seconds);
},
// 计算两个日期之间的天数
daysBetween(date1, date2) {
const oneDay = 24 * 60 * 60 * 1000;
const firstDate = new Date(date1);
const secondDate = new Date(date2);
return Math.round(Math.abs((firstDate - secondDate) / oneDay));
},
// 获取相对时间
relativeTime(date) {
const now = new Date();
const target = new Date(date);
const diffInSeconds = Math.floor((now - target) / 1000);
if (diffInSeconds < 60) {
return "刚刚";
} else if (diffInSeconds < 3600) {
return `${Math.floor(diffInSeconds / 60)}分钟前`;
} else if (diffInSeconds < 86400) {
return `${Math.floor(diffInSeconds / 3600)}小时前`;
} else if (diffInSeconds < 2592000) {
return `${Math.floor(diffInSeconds / 86400)}天前`;
} else {
return this.format(date);
}
}
};
}
// 导出
// module.exports = CustomUtils;
// 使用示例
console.log(CustomUtils.array.chunk([1, 2, 3, 4, 5, 6, 7, 8], 3));
console.log(CustomUtils.array.unique([1, 2, 2, 3, 3, 4]));
console.log(CustomUtils.object.deepClone({ a: 1, b: { c: 2 } }));
console.log(CustomUtils.string.camelCase("hello-world"));
console.log(CustomUtils.number.format(1234567.89));
console.log(CustomUtils.date.format(new Date(), "YYYY年MM月DD日 HH:mm:ss"));库的管理和优化
包管理
json
{
"name": "my-project",
"version": "1.0.0",
"description": "我的 JavaScript 项目",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"build": "webpack --mode production",
"test": "jest"
},
"dependencies": {
"axios": "^1.6.0",
"lodash": "^4.17.21"
},
"devDependencies": {
"webpack": "^5.89.0",
"webpack-cli": "^5.1.4",
"jest": "^29.7.0",
"nodemon": "^3.0.1"
},
"engines": {
"node": ">=14.0.0"
}
}性能优化
javascript
// Tree Shaking 配置 (webpack.config.js)
module.exports = {
mode: 'production',
optimization: {
usedExports: true,
sideEffects: false
}
};
// 代码分割
// 动态导入
async function loadLodash() {
const { chunk } = await import('lodash/chunk');
return chunk([1, 2, 3, 4, 5], 2);
}
// 预加载
const importantLibrary = import('important-library');
// 懒加载
document.getElementById('button').addEventListener('click', async () => {
const { default: Chart } = await import('chart.js');
// 使用图表库
});
// Bundle 分析
// 安装: npm install --save-dev webpack-bundle-analyzer
// 配置:
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
module.exports = {
plugins: [
new BundleAnalyzerPlugin()
]
};实际应用示例
1. 综合工具库
javascript
// comprehensive-utils.js
class ComprehensiveUtils {
// HTTP 工具
static http = {
// 简单的 fetch 封装
async request(url, options = {}) {
const defaultOptions = {
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
};
const config = { ...defaultOptions, ...options };
try {
const response = await fetch(url, config);
if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}
const contentType = response.headers.get('content-type');
if (contentType && contentType.includes('application/json')) {
return await response.json();
}
return await response.text();
} catch (error) {
throw new Error(`请求失败: ${error.message}`);
}
},
get(url, options = {}) {
return this.request(url, { ...options, method: 'GET' });
},
post(url, data, options = {}) {
return this.request(url, {
...options,
method: 'POST',
body: JSON.stringify(data)
});
},
put(url, data, options = {}) {
return this.request(url, {
...options,
method: 'PUT',
body: JSON.stringify(data)
});
},
delete(url, options = {}) {
return this.request(url, { ...options, method: 'DELETE' });
}
};
// 存储工具
static storage = {
// 本地存储
local: {
set(key, value) {
try {
localStorage.setItem(key, JSON.stringify(value));
return true;
} catch (error) {
console.error('本地存储设置失败:', error);
return false;
}
},
get(key, defaultValue = null) {
try {
const item = localStorage.getItem(key);
return item ? JSON.parse(item) : defaultValue;
} catch (error) {
console.error('本地存储获取失败:', error);
return defaultValue;
}
},
remove(key) {
try {
localStorage.removeItem(key);
return true;
} catch (error) {
console.error('本地存储删除失败:', error);
return false;
}
},
clear() {
try {
localStorage.clear();
return true;
} catch (error) {
console.error('本地存储清空失败:', error);
return false;
}
}
},
// 会话存储
session: {
set(key, value) {
try {
sessionStorage.setItem(key, JSON.stringify(value));
return true;
} catch (error) {
console.error('会话存储设置失败:', error);
return false;
}
},
get(key, defaultValue = null) {
try {
const item = sessionStorage.getItem(key);
return item ? JSON.parse(item) : defaultValue;
} catch (error) {
console.error('会话存储获取失败:', error);
return defaultValue;
}
},
remove(key) {
try {
sessionStorage.removeItem(key);
return true;
} catch (error) {
console.error('会话存储删除失败:', error);
return false;
}
},
clear() {
try {
sessionStorage.clear();
return true;
} catch (error) {
console.error('会话存储清空失败:', error);
return false;
}
}
}
};
// 验证工具
static validation = {
// 邮箱验证
isEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(email);
},
// 手机号验证
isPhoneNumber(phone) {
const phoneRegex = /^1[3-9]\d{9}$/;
return phoneRegex.test(phone);
},
// 身份证验证
isIdCard(idCard) {
const idCardRegex = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
return idCardRegex.test(idCard);
},
// URL 验证
isUrl(url) {
try {
new URL(url);
return true;
} catch {
return false;
}
},
// 数字验证
isNumber(value) {
return !isNaN(parseFloat(value)) && isFinite(value);
},
// 整数验证
isInteger(value) {
return Number.isInteger(Number(value));
}
};
// 格式化工具
static format = {
// 货币格式化
currency(amount, currency = "CNY", locale = "zh-CN") {
return new Intl.NumberFormat(locale, {
style: "currency",
currency: currency
}).format(amount);
},
// 日期格式化
date(date, locale = "zh-CN") {
return new Intl.DateTimeFormat(locale).format(new Date(date));
},
// 数字格式化
number(number, options = {}) {
return new Intl.NumberFormat("zh-CN", options).format(number);
},
// 字节格式化
bytes(bytes) {
if (bytes === 0) return "0 Bytes";
const k = 1024;
const sizes = ["Bytes", "KB", "MB", "GB", "TB"];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
}
};
// 设备检测工具
static device = {
// 检测是否为移动端
isMobile() {
return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent);
},
// 检测是否为微信浏览器
isWechat() {
return /MicroMessenger/i.test(navigator.userAgent);
},
// 检测是否为 iOS
isIOS() {
return /iPad|iPhone|iPod/.test(navigator.userAgent);
},
// 检测是否为 Android
isAndroid() {
return /Android/.test(navigator.userAgent);
},
// 获取屏幕信息
getScreenInfo() {
return {
width: screen.width,
height: screen.height,
availWidth: screen.availWidth,
availHeight: screen.availHeight,
colorDepth: screen.colorDepth,
pixelDepth: screen.pixelDepth
};
},
// 获取窗口信息
getWindowInfo() {
return {
width: window.innerWidth,
height: window.innerHeight,
scrollX: window.scrollX,
scrollY: window.scrollY
};
}
};
// 性能监控工具
static performance = {
// 获取页面加载时间
getPageLoadTime() {
if (performance && performance.timing) {
const timing = performance.timing;
return {
dns: timing.domainLookupEnd - timing.domainLookupStart,
tcp: timing.connectEnd - timing.connectStart,
request: timing.responseStart - timing.requestStart,
response: timing.responseEnd - timing.responseStart,
dom: timing.domContentLoadedEventEnd - timing.navigationStart,
load: timing.loadEventEnd - timing.navigationStart
};
}
return null;
},
// 测量函数执行时间
measureFunction(fn, ...args) {
const start = performance.now();
const result = fn(...args);
const end = performance.now();
return {
result: result,
duration: end - start
};
},
// 内存使用情况
getMemoryUsage() {
if (performance.memory) {
const memory = performance.memory;
return {
used: memory.usedJSHeapSize,
total: memory.totalJSHeapSize,
limit: memory.jsHeapSizeLimit
};
}
return null;
}
};
}
// 使用示例
// HTTP 请求
// ComprehensiveUtils.http.get('https://api.github.com/users/octocat')
// .then(data => console.log(data))
// .catch(error => console.error(error));
// 存储操作
ComprehensiveUtils.storage.local.set('user', { name: '张三', age: 25 });
console.log(ComprehensiveUtils.storage.local.get('user'));
// 验证操作
console.log(ComprehensiveUtils.validation.isEmail('test@example.com')); // true
console.log(ComprehensiveUtils.validation.isPhoneNumber('13812345678')); // true
// 格式化操作
console.log(ComprehensiveUtils.format.currency(1234.56)); // "¥1,234.56"
console.log(ComprehensiveUtils.format.bytes(1024)); // "1 KB"
// 设备检测
console.log(ComprehensiveUtils.device.isMobile());
console.log(ComprehensiveUtils.device.getScreenInfo());
// 性能监控
console.log(ComprehensiveUtils.performance.getPageLoadTime());2. 项目脚手架工具
javascript
// scaffold.js - 项目脚手架工具
class ProjectScaffold {
constructor() {
this.templates = {
'basic': {
name: '基础项目模板',
files: [
{ path: 'package.json', content: this.getPackageJson('basic') },
{ path: 'index.js', content: this.getIndexJs() },
{ path: 'README.md', content: this.getReadme('basic') },
{ path: '.gitignore', content: this.getGitignore() }
]
},
'express': {
name: 'Express 项目模板',
dependencies: ['express'],
files: [
{ path: 'package.json', content: this.getPackageJson('express') },
{ path: 'app.js', content: this.getExpressApp() },
{ path: 'routes/index.js', content: this.getExpressRoutes() },
{ path: 'README.md', content: this.getReadme('express') },
{ path: '.gitignore', content: this.getGitignore() }
]
},
'react': {
name: 'React 项目模板',
dependencies: ['react', 'react-dom'],
devDependencies: ['webpack', 'webpack-cli', 'babel-loader'],
files: [
{ path: 'package.json', content: this.getPackageJson('react') },
{ path: 'src/index.js', content: this.getReactIndex() },
{ path: 'src/App.js', content: this.getReactApp() },
{ path: 'public/index.html', content: this.getHtmlTemplate() },
{ path: 'webpack.config.js', content: this.getWebpackConfig() },
{ path: 'README.md', content: this.getReadme('react') },
{ path: '.gitignore', content: this.getGitignore() }
]
}
};
}
getPackageJson(template) {
const base = {
name: `my-${template}-project`,
version: "1.0.0",
description: `${template} 项目`,
main: "index.js",
scripts: {
start: "node index.js",
dev: "nodemon index.js"
},
keywords: [template],
author: "Your Name",
license: "MIT"
};
if (this.templates[template].dependencies) {
base.dependencies = {};
this.templates[template].dependencies.forEach(dep => {
base.dependencies[dep] = "^latest";
});
}
if (this.templates[template].devDependencies) {
base.devDependencies = {};
this.templates[template].devDependencies.forEach(dep => {
base.devDependencies[dep] = "^latest";
});
}
return JSON.stringify(base, null, 2);
}
getIndexJs() {
return `console.log('Hello, World!');`;
}
getExpressApp() {
return `const express = require('express');
const app = express();
const port = process.env.PORT || 3000;
app.use(express.json());
app.get('/', (req, res) => {
res.send('Hello World!');
});
app.listen(port, () => {
console.log(\`Server running at http://localhost:\${port}\`);
});
module.exports = app;`;
}
getExpressRoutes() {
return `const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.json({ message: 'Welcome to the API' });
});
module.exports = router;`;
}
getReactIndex() {
return `import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);`;
}
getReactApp() {
return `import React from 'react';
function App() {
return (
<div className="App">
<h1>Hello, React!</h1>
</div>
);
}
export default App;`;
}
getHtmlTemplate() {
return `<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>`;
}
getWebpackConfig() {
return `const path = require('path');
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\\.jsx?$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react']
}
}
}
]
}
};`;
}
getReadme(template) {
return `# ${this.templates[template].name}
## 项目介绍
这是一个 ${this.templates[template].name}。
## 安装依赖
\`\`\`bash
npm install
\`\`\`
## 启动项目
\`\`\`bash
npm start
\`\`\`
## 开发模式
\`\`\`bash
npm run dev
\`\`\``;
}
getGitignore() {
return `node_modules/
npm-debug.log*
.DS_Store
.env
dist/
build/`;
}
async createProject(template, projectName) {
if (!this.templates[template]) {
throw new Error(`不支持的模板: ${template}`);
}
const projectPath = `./${projectName}`;
// 创建项目目录
// await fs.mkdir(projectPath, { recursive: true });
// 创建文件
for (const file of this.templates[template].files) {
const filePath = \`\${projectPath}/\${file.path}\`;
const dirPath = filePath.substring(0, filePath.lastIndexOf('/'));
// 创建目录
// await fs.mkdir(dirPath, { recursive: true });
// 创建文件
// await fs.writeFile(filePath, file.content);
console.log(\`创建文件: \${filePath}\`);
}
console.log(\`项目 \${projectName} 创建成功!`);
console.log('支持的模板:');
Object.keys(this.templates).forEach(key => {
console.log(\` - \${key}: \${this.templates[key].name}\`);
});
}
}
// 使用示例
// const scaffold = new ProjectScaffold();
// scaffold.createProject('basic', 'my-new-project');总结
JavaScript 库的核心要点:
- 基本概念:预先编写好的代码集合,解决特定问题
- 常用库:Lodash、Moment.js、Axios、D3.js、Three.js 等
- 选择标准:功能性、性能、稳定性、社区支持等
- 使用方式:npm 安装、按需加载、Tree Shaking 优化
- 自定义库:创建自己的工具库,满足特定需求
- 管理优化:包管理、性能优化、代码分割
- 实际应用:综合工具库、项目脚手架等
合理使用 JavaScript 库可以大大提高开发效率,但也要注意避免过度依赖,根据项目需求选择合适的库。在下一章节中,我们将学习 JavaScript 的学习资源。