Skip to content

JavaScript 库

JavaScript 库是预先编写好的代码集合,提供了特定功能的封装,可以简化开发过程、提高开发效率。在现代 JavaScript 开发中,合理使用库可以大大减少重复工作,提升代码质量。在本章节中,我们将学习 JavaScript 中常用的库及其使用方法。

什么是 JavaScript 库

JavaScript 库是一组预先编写好的 JavaScript 代码,封装了特定功能,供开发者在项目中重复使用。库通常解决特定领域的问题,如 DOM 操作、动画效果、数据处理等。

库的特点

  1. 功能专一:专注于解决特定问题
  2. 可重用性:可以在多个项目中使用
  3. 封装性:隐藏实现细节,提供简洁接口
  4. 标准化:遵循行业标准和最佳实践
  5. 社区支持:通常有活跃的社区维护

常用 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 库的核心要点:

  1. 基本概念:预先编写好的代码集合,解决特定问题
  2. 常用库:Lodash、Moment.js、Axios、D3.js、Three.js 等
  3. 选择标准:功能性、性能、稳定性、社区支持等
  4. 使用方式:npm 安装、按需加载、Tree Shaking 优化
  5. 自定义库:创建自己的工具库,满足特定需求
  6. 管理优化:包管理、性能优化、代码分割
  7. 实际应用:综合工具库、项目脚手架等

合理使用 JavaScript 库可以大大提高开发效率,但也要注意避免过度依赖,根据项目需求选择合适的库。在下一章节中,我们将学习 JavaScript 的学习资源。

本站内容仅供学习和研究使用。