1. JavaScript常用库函数概览作为一名前端开发者我每天都要和各种JavaScript库函数打交道。这些看似简单的工具函数实际上构成了我们日常开发的基石。记得刚入行时我总是习惯性地重复造轮子直到有次看到同事用一行Array.prototype.map()就解决了我写了20多行循环代码的问题才真正意识到掌握这些基础库函数的重要性。JavaScript的标准库函数主要分布在以下几个核心对象上Array处理数组操作的利器String字符串处理的瑞士军刀Object对象操作的基础工具Math数学计算的宝库Date日期时间处理的必备工具JSON数据格式转换的标准方案这些函数之所以被称为常用是因为它们被ECMAScript标准定义所有JavaScript环境都支持解决了80%的日常开发需求经过多年优化性能有保障具有一致的API设计学习成本低2. 数组操作从forEach到reduce2.1 遍历类函数实战forEach是我最早接触的数组方法但直到踩过几次坑才真正理解它const arr [1, 2, 3]; arr.forEach((item, index) { console.log(第${index}个元素是${item}); if(index 1) arr.push(4); // 不会影响本次遍历 });注意forEach无法用break中断使用return也只是跳过当前项而非退出循环map和forEach最大的区别在于它会返回新数组const users [{name:Alice}, {name:Bob}]; const names users.map(user { return user.name.toUpperCase(); // 必须显式return }); console.log(names); // [ALICE, BOB]2.2 查找筛选三剑客filter、find和findIndex构成了数据筛选的黄金组合const products [ {id:1, stock:0}, {id:2, stock:5}, {id:3, stock:2} ]; // filter返回所有匹配项 const available products.filter(p p.stock 0); console.log(available.length); // 2 // find只返回第一个匹配项 const firstAvailable products.find(p p.stock 0); console.log(firstAvailable.id); // 2 // findIndex返回索引 const index products.findIndex(p p.stock 3); console.log(index); // 12.3 reduce的进阶用法reduce是最强大的数组方法但也是最难掌握的。这个统计词频的例子展示了它的威力const words [hello, world, hello]; const wordCount words.reduce((acc, word) { acc[word] (acc[word] || 0) 1; return acc; }, {}); console.log(wordCount); // {hello: 2, world: 1}更实用的一个场景是表单数据收集const formFields [ {name: username, value: Alice}, {name: age, value: 25} ]; const formData formFields.reduce((data, field) { data[field.name] field.value; return data; }, {}); console.log(formData); // {username: Alice, age: 25}3. 字符串处理的精髓3.1 模板字符串的妙用自从ES6引入模板字符串字符串拼接变得无比优雅const user {name: Bob, age: 30}; console.log(用户${user.name}今年${user.age}岁); // 更高级的用法带标签的模板字符串 function highlight(strings, ...values) { return strings.reduce((result, str, i) { return ${result}${str}mark${values[i] || }/mark; }, ); } const message highlight重要通知${user.name}的账户存在异常; console.log(message); // 重要通知markBob/mark的账户存在异常3.2 正则相关方法match、search、replace这三个方法与正则表达式配合使用威力巨大const text 订单号123-4567-890; // 提取订单号 const orderNo text.match(/\d{3}-\d{4}-\d{3}/)[0]; console.log(orderNo); // 123-4567-890 // 安全替换 const masked text.replace(/\d/g, *); console.log(masked); // 订单号***-****-***3.3 实用工具方法padStart和padEnd在处理格式化输出时特别有用// 时间格式化 const minutes 5; const seconds 7; console.log(${minutes.padStart(2,0)}:${seconds.padEnd(2,0)}); // 05:70 // 表格对齐 const products [ {name: iPhone, price: 999}, {name: MacBook Pro, price: 1999} ]; products.forEach(p { console.log(${p.name.padEnd(15)} | ${p.price.toString().padStart(6)}$); }); // iPhone | 999$ // MacBook Pro | 1999$4. 对象操作的现代方式4.1 对象属性遍历Object.keys、Object.values和Object.entries构成了对象遍历的三驾马车const user { name: Alice, age: 25, [Symbol(id)]: 123 // 符号属性 }; // 获取可枚举属性 console.log(Object.keys(user)); // [name, age] console.log(Object.values(user)); // [Alice, 25] console.log(Object.entries(user)); // [[name, Alice], [age, 25]] // 包含不可枚举属性 console.log(Object.getOwnPropertyNames(user)); // [name, age] console.log(Object.getOwnPropertySymbols(user)); // [Symbol(id)]4.2 对象合并与克隆Object.assign和展开运算符(...)是现代JavaScript对象复制的首选方式const defaults {theme: light, fontSize: 14}; const userSettings {fontSize: 16}; // 浅合并 const settings Object.assign({}, defaults, userSettings); console.log(settings); // {theme: light, fontSize: 16} // 使用展开运算符更直观 const newSettings {...defaults, ...userSettings}; // 深克隆方案 const deepClone obj JSON.parse(JSON.stringify(obj)); const nestedObj {a: {b: 1}}; const cloned deepClone(nestedObj); console.log(cloned.a nestedObj.a); // false4.3 属性描述符操作Object.defineProperty让我们可以精细控制对象属性const book {title: JavaScript高级编程}; Object.defineProperty(book, price, { value: 99, writable: false, // 不可写 enumerable: true, // 可枚举 configurable: false // 不可删除 }); console.log(book.price); // 99 book.price 100; // 静默失败严格模式下会报错 console.log(book.price); // 995. 数学与日期处理5.1 Math的实用方法Math对象提供了各种数学计算工具// 随机数生成 function getRandom(min, max) { return Math.floor(Math.random() * (max - min 1)) min; } console.log(getRandom(1, 10)); // 1到10的随机整数 // 数值处理 console.log(Math.trunc(3.14)); // 3 (直接取整) console.log(Math.round(3.5)); // 4 (四舍五入) console.log(Math.ceil(3.1)); // 4 (向上取整) console.log(Math.floor(3.9)); // 3 (向下取整) // 最大值/最小值 console.log(Math.max(...[1, 2, 3])); // 3 console.log(Math.min(1, 2, 3)); // 15.2 日期处理技巧JavaScript的Date对象虽然饱受诟病但掌握后也能得心应手// 创建日期 const now new Date(); const specificDate new Date(2023, 5, 15); // 注意月份是0-based // 格式化输出 console.log(now.toLocaleDateString(zh-CN)); // 2023/6/15 console.log(now.toISOString()); // 2023-06-15T08:00:00.000Z // 日期计算 const tomorrow new Date(now); tomorrow.setDate(now.getDate() 1); // 日期差值毫秒 const diff tomorrow - now; console.log(diff / (1000 * 60 * 60 * 24)); // 1天6. JSON数据转换6.1 基本序列化与反序列化JSON.stringify和JSON.parse是处理JSON数据的黄金搭档const user { name: Alice, age: 25, lastLogin: new Date(), sayHi() { console.log(Hi!); } }; const jsonStr JSON.stringify(user); console.log(jsonStr); // {name:Alice,age:25,lastLogin:2023-06-15T08:00:00.000Z} // 注意函数被忽略了日期被转为字符串 const revivedUser JSON.parse(jsonStr); console.log(revivedUser.lastLogin); // 字符串而非Date对象6.2 高级序列化控制通过replacer和reviver函数可以实现精细控制const product { id: 123, name: Laptop, price: 999, secretKey: abc123 }; // 序列化时排除secretKey const json JSON.stringify(product, (key, value) { return key secretKey ? undefined : value; }); console.log(json); // {id:123,name:Laptop,price:999} // 反序列化时恢复Date对象 const str {date:2023-06-15T08:00:00.000Z}; const data JSON.parse(str, (key, value) { if (typeof value string /^\d{4}-\d{2}-\d{2}T/.test(value)) { return new Date(value); } return value; }); console.log(data.date instanceof Date); // true7. 其他实用工具函数7.1 类型判断全家桶JavaScript的类型判断一直是个痛点这些方法可以帮我们// 基本类型判断 console.log(typeof 42); // number console.log(typeof text); // string console.log(typeof true); // boolean console.log(typeof undefined); // undefined console.log(typeof Symbol()); // symbol console.log(typeof null); // object (历史遗留问题) // 更准确的类型判断 console.log(Object.prototype.toString.call([])); // [object Array] console.log(Object.prototype.toString.call(new Date())); // [object Date] // 现代API console.log(Array.isArray([])); // true console.log(Number.isNaN(NaN)); // true7.2 全局函数解析parseInt和parseFloat虽然常用但容易踩坑console.log(parseInt(08)); // 8 (ES5) console.log(parseInt(08, 10)); // 8 (明确指定基数更安全) console.log(parseInt(0x10)); // 16 (十六进制) console.log(parseFloat(3.14.15)); // 3.14 (遇到第二个小数点停止)isNaN和Number.isNaN的区别console.log(isNaN(text)); // true (先尝试转换为数字) console.log(Number.isNaN(text)); // false (严格判断)7.3 异步编程基础虽然Promise和async/await已经成为主流但回调风格的API仍大量存在// 传统回调 function fetchData(callback) { setTimeout(() { callback(null, {data: some data}); }, 1000); } // 转换为Promise function fetchDataAsync() { return new Promise((resolve, reject) { fetchData((err, result) { if (err) reject(err); else resolve(result); }); }); } // 使用async/await async function process() { try { const data await fetchDataAsync(); console.log(data); } catch (error) { console.error(error); } }8. 实战中的经验与陷阱8.1 性能优化要点数组方法的选择会影响性能const bigArray new Array(1000000).fill(1); console.time(for); let sum 0; for (let i 0; i bigArray.length; i) { sum bigArray[i]; } console.timeEnd(for); // ~5ms console.time(forEach); sum 0; bigArray.forEach(n sum n); console.timeEnd(forEach); // ~15ms console.time(reduce); sum bigArray.reduce((acc, n) acc n, 0); console.timeEnd(reduce); // ~20ms提示在超大数据集上传统for循环通常性能最好8.2 常见陷阱规避数组的sort陷阱const nums [10, 5, 80, 1]; nums.sort(); console.log(nums); // [1, 10, 5, 80] (按字符串排序) // 正确做法 nums.sort((a, b) a - b); console.log(nums); // [1, 5, 10, 80]浮点数精度问题console.log(0.1 0.2 0.3); // false console.log(0.1 0.2); // 0.30000000000000004 // 解决方案 function isEqual(a, b, epsilon 1e-10) { return Math.abs(a - b) epsilon; }this绑定问题const counter { count: 0, increment: function() { setInterval(function() { this.count; // 这里的this指向window/undefined console.log(this.count); }, 1000); } }; // 解决方案1箭头函数 const counter2 { count: 0, increment: function() { setInterval(() { this.count; console.log(this.count); }, 1000); } }; // 解决方案2bind const counter3 { count: 0, increment: function() { setInterval(function() { this.count; console.log(this.count); }.bind(this), 1000); } };8.3 现代JavaScript新特性可选链操作符(?.)const user { profile: { name: Alice } }; // 传统写法 const name user user.profile user.profile.name; // 现代写法 const name user?.profile?.name;空值合并运算符(??)const config { timeout: 0 }; // 传统写法 const timeout config.timeout ! undefined ? config.timeout : 3000; // 现代写法 const timeout config.timeout ?? 3000; console.log(timeout); // 0 (因为0不是null/undefined)Object.hasOwn替代in操作符const obj { a: 1 }; console.log(a in obj); // true (包括原型链) console.log(Object.hasOwn(obj, a)); // true (仅自身属性) console.log(Object.hasOwn(obj, toString)); // false