JavaScript函数全解析:从基础到高阶应用

📅 2026/7/22 7:19:28
JavaScript函数全解析:从基础到高阶应用
1. JavaScript函数基础与核心概念JavaScript函数是这门语言最基础也是最重要的组成部分之一。作为一门函数式编程语言JavaScript中的函数不仅仅是执行特定任务的代码块更是一等公民First-class citizen这意味着函数可以像其他数据类型一样被传递和使用。1.1 函数定义方式在JavaScript中函数主要有三种定义方式函数声明Function Declarationfunction square(number) { return number * number; }特点存在函数提升hoisting可以在定义前调用。函数表达式Function Expressionconst square function(number) { return number * number; };特点不存在提升必须在定义后使用。箭头函数Arrow FunctionES6新增const square (number) number * number;特点简洁语法不绑定自己的this、arguments、super或new.target。提示箭头函数在单参数时可省略括号单行时可省略return和花括号但多行时必须使用return。1.2 函数参数处理JavaScript函数的参数处理非常灵活默认参数ES6function greet(name Guest) { console.log(Hello, ${name}!); }剩余参数Rest Parametersfunction sum(...numbers) { return numbers.reduce((acc, num) acc num, 0); }arguments对象传统方式function showArgs() { console.log(arguments); // 类数组对象 }注意箭头函数没有自己的arguments对象但可以访问外围函数的arguments。2. 常用内置函数分类解析2.1 数据类型转换函数parseInt()parseInt(10); // 10 parseInt(101, 2); // 5 (二进制转换)parseFloat()parseFloat(3.14); // 3.14Number()Number(123); // 123 Number(true); // 1String()String(123); // 123 String(null); // nullBoolean()Boolean(); // false Boolean(0); // false Boolean([]); // true2.2 数学计算函数Math对象常用方法Math.abs(-5); // 5 Math.ceil(4.2); // 5 Math.floor(4.9); // 4 Math.round(4.5); // 5 Math.max(1, 3, 2); // 3 Math.min(1, 3, 2); // 1 Math.random(); // 0~1之间的随机数 Math.pow(2, 3); // 8 (ES7可用2**3)指数和对数函数Math.exp(1); // e的1次方 ≈ 2.718 Math.log(Math.E); // 1 (自然对数) Math.log10(100); // 2 Math.log2(8); // 32.3 字符串处理函数基本字符串方法hello.charAt(1); // e hello.concat( world); // hello world hello.includes(ell); // true hello.indexOf(l); // 2 hello.lastIndexOf(l); // 3 hello.slice(1, 3); // el hello.substring(1, 3); // el hello.substr(1, 3); // ell (已废弃) hello.repeat(2); // hellohello大小写转换Hello.toLowerCase(); // hello hello.toUpperCase(); // HELLOtrim系列 hello .trim(); // hello hello .trimStart(); // hello hello .trimEnd(); // helloES6新增方法hello.startsWith(he); // true hello.endsWith(lo); // true hello.padStart(8, *); // ***hello hello.padEnd(8, *); // hello***2.4 数组操作函数基本数组方法const arr [1, 2, 3]; arr.push(4); // [1,2,3,4] arr.pop(); // [1,2,3] arr.unshift(0); // [0,1,2,3] arr.shift(); // [1,2,3] arr.concat([4,5]); // [1,2,3,4,5] arr.join(-); // 1-2-3 arr.reverse(); // [3,2,1] arr.slice(1,3); // [2,3] arr.splice(1,1,a); // [1,a,3] (原数组变为[1,a,3])搜索和位置方法[1,2,3].indexOf(2); // 1 [1,2,3].lastIndexOf(2); // 1 [1,2,3].includes(2); // true [1,2,3].find(x x 1); // 2 [1,2,3].findIndex(x x 1); // 1迭代方法[1,2,3].forEach(x console.log(x)); [1,2,3].map(x x * 2); // [2,4,6] [1,2,3].filter(x x 1); // [2,3] [1,2,3].reduce((acc, x) acc x, 0); // 6 [1,2,3].some(x x 2); // true [1,2,3].every(x x 0); // trueES6新增方法Array.from(hello); // [h,e,l,l,o] Array.of(1,2,3); // [1,2,3] [1,2,3].fill(0); // [0,0,0] [1,2,3].copyWithin(0,1); // [2,3,3] [1,[2,3]].flat(); // [1,2,3] [1,2,3].flatMap(x [x, x*2]); // [1,2,2,4,3,6]2.5 对象相关函数对象属性操作const obj {a:1, b:2}; Object.keys(obj); // [a,b] Object.values(obj); // [1,2] Object.entries(obj); // [[a,1],[b,2]] Object.assign({}, obj, {b:3}); // {a:1,b:3} Object.freeze(obj); // 冻结对象 Object.seal(obj); // 密封对象原型相关方法Object.create(proto); Object.getPrototypeOf(obj); Object.setPrototypeOf(obj, proto);属性描述符Object.getOwnPropertyDescriptor(obj, a); Object.defineProperty(obj, c, {value:3}); Object.defineProperties(obj, {c:{value:3},d:{value:4}});2.6 日期时间函数Date构造函数new Date(); // 当前时间 new Date(2023, 0, 1); // 2023年1月1日 new Date(2023-01-01); // ISO格式日期常用实例方法const now new Date(); now.getFullYear(); // 年份 now.getMonth(); // 月份(0-11) now.getDate(); // 日期(1-31) now.getHours(); // 小时(0-23) now.getMinutes(); // 分钟(0-59) now.getSeconds(); // 秒数(0-59) now.getTime(); // 时间戳(毫秒) now.toISOString(); // ISO格式字符串 now.toLocaleString(); // 本地格式字符串日期计算const date new Date(); date.setDate(date.getDate() 7); // 一周后2.7 JSON处理函数JSON.stringify()JSON.stringify({a:1, b:2}); // {a:1,b:2} JSON.stringify({a:1, b:2}, null, 2); // 带缩进的格式化输出JSON.parse()JSON.parse({a:1,b:2}); // {a:1, b:2}注意JSON.stringify会忽略函数和undefined属性Date对象会被转为ISO字符串。3. 高阶函数与函数式编程3.1 高阶函数概念高阶函数是指可以接收函数作为参数或者返回函数作为结果的函数。JavaScript中常见的高阶函数包括// 接收函数作为参数 function operate(a, b, operation) { return operation(a, b); } // 返回函数 function multiplier(factor) { return function(x) { return x * factor; }; }3.2 常见高阶函数模式函数柯里化function curry(fn) { return function curried(...args) { if (args.length fn.length) { return fn.apply(this, args); } else { return function(...args2) { return curried.apply(this, args.concat(args2)); }; } }; } const add (a, b, c) a b c; const curriedAdd curry(add); curriedAdd(1)(2)(3); // 6函数组合function compose(...fns) { return function(x) { return fns.reduceRight((acc, fn) fn(acc), x); }; } const add1 x x 1; const double x x * 2; const addThenDouble compose(double, add1); addThenDouble(5); // 12记忆化函数function memoize(fn) { const cache new Map(); return function(...args) { const key JSON.stringify(args); if (cache.has(key)) return cache.get(key); const result fn.apply(this, args); cache.set(key, result); return result; }; } const factorial memoize(n n 1 ? 1 : n * factorial(n - 1));3.3 函数式编程工具函数节流(throttle)函数function throttle(fn, delay) { let lastCall 0; return function(...args) { const now Date.now(); if (now - lastCall delay) { lastCall now; return fn.apply(this, args); } }; }防抖(debounce)函数function debounce(fn, delay) { let timer; return function(...args) { clearTimeout(timer); timer setTimeout(() fn.apply(this, args), delay); }; }单次执行函数function once(fn) { let called false; return function(...args) { if (!called) { called true; return fn.apply(this, args); } }; }4. 异步编程相关函数4.1 Promise相关函数Promise构造函数new Promise((resolve, reject) { // 异步操作 if (success) resolve(value); else reject(error); });Promise静态方法Promise.resolve(value); // 返回一个已解决的Promise Promise.reject(error); // 返回一个已拒绝的Promise Promise.all([p1, p2]); // 所有Promise都解决时解决 Promise.allSettled([p1, p2]); // 所有Promise都完成时解决 Promise.race([p1, p2]); // 第一个完成的Promise Promise.any([p1, p2]); // 第一个解决的PromisePromise实例方法promise.then(onFulfilled, onRejected); promise.catch(onRejected); promise.finally(onFinally);4.2 async/await函数async函数声明async function fetchData() { const response await fetch(url); const data await response.json(); return data; }async函数表达式const fetchData async function() { // ... };async箭头函数const fetchData async () { // ... };4.3 定时器函数setTimeoutconst timerId setTimeout(() { console.log(Delayed message); }, 1000); clearTimeout(timerId); // 取消定时器setIntervalconst intervalId setInterval(() { console.log(Repeating message); }, 1000); clearInterval(intervalId); // 清除间隔requestAnimationFramefunction animate() { // 动画逻辑 requestAnimationFrame(animate); } requestAnimationFrame(animate);5. 实用函数与技巧5.1 类型检查函数基本类型检查typeof 42; // number typeof str; // string typeof true; // boolean typeof undefined; // undefined typeof null; // object (历史遗留问题) typeof {}; // object typeof []; // object typeof function(){}; // function更精确的类型检查Object.prototype.toString.call([]); // [object Array] Object.prototype.toString.call(null); // [object Null] Array.isArray([]); // true自定义类型检查function isPlainObject(obj) { return Object.prototype.toString.call(obj) [object Object] Object.getPrototypeOf(obj) Object.prototype; }5.2 实用工具函数深度克隆function deepClone(obj) { if (obj null || typeof obj ! object) return obj; const clone Array.isArray(obj) ? [] : {}; for (const key in obj) { if (obj.hasOwnProperty(key)) { clone[key] deepClone(obj[key]); } } return clone; }对象合并function deepMerge(target, source) { for (const key in source) { if (source.hasOwnProperty(key)) { if (typeof source[key] object source[key] ! null) { if (!target[key]) target[key] Array.isArray(source[key]) ? [] : {}; deepMerge(target[key], source[key]); } else { target[key] source[key]; } } } return target; }函数执行时间测量function measureTime(fn) { return function(...args) { const start performance.now(); const result fn.apply(this, args); const end performance.now(); console.log(Execution time: ${end - start}ms); return result; }; }5.3 函数式编程实用函数管道函数function pipe(...fns) { return function(x) { return fns.reduce((acc, fn) fn(acc), x); }; } const process pipe( x x 1, x x * 2, x x - 3 ); process(5); // (51)*2-3 9偏函数应用function partial(fn, ...presetArgs) { return function(...laterArgs) { return fn(...presetArgs, ...laterArgs); }; } const add (a, b) a b; const add5 partial(add, 5); add5(3); // 8惰性求值函数function lazy(fn) { let result; let evaluated false; return function() { if (!evaluated) { result fn.apply(this, arguments); evaluated true; } return result; }; } const expensiveCalc lazy(() { console.log(Calculating...); return 42; }); expensiveCalc(); // 第一次调用会计算 expensiveCalc(); // 第二次直接返回缓存结果6. 浏览器环境特有函数6.1 DOM操作函数元素选择document.getElementById(id); document.querySelector(.class); document.querySelectorAll(div);元素创建与修改document.createElement(div); element.textContent text; element.innerHTML spanHTML/span; element.setAttribute(data-id, 123); element.classList.add(active);事件处理element.addEventListener(click, handler); element.removeEventListener(click, handler); element.dispatchEvent(new Event(click));6.2 BOM相关函数窗口控制window.open(url, _blank); window.close(); window.scrollTo(x, y);存储相关localStorage.setItem(key, value); localStorage.getItem(key); sessionStorage.setItem(key, value);导航相关location.href https://example.com; location.reload(); history.pushState(state, title, url);6.3 网络请求函数Fetch APIfetch(url, { method: POST, headers: {Content-Type: application/json}, body: JSON.stringify(data) }) .then(response response.json()) .then(data console.log(data)) .catch(error console.error(error));XMLHttpRequest传统方式const xhr new XMLHttpRequest(); xhr.open(GET, url); xhr.onload function() { if (xhr.status 200) console.log(xhr.responseText); }; xhr.send();WebSocketconst socket new WebSocket(ws://example.com); socket.onopen () socket.send(Hello); socket.onmessage event console.log(event.data);7. Node.js环境特有函数7.1 文件系统函数回调风格const fs require(fs); fs.readFile(file.txt, utf8, (err, data) { if (err) throw err; console.log(data); });Promise风格const fs require(fs).promises; fs.readFile(file.txt, utf8) .then(data console.log(data)) .catch(err console.error(err));同步风格const data fs.readFileSync(file.txt, utf8);7.2 路径处理函数path模块const path require(path); path.join(/foo, bar, baz); // /foo/bar/baz path.resolve(foo, bar); // 绝对路径 path.dirname(/foo/bar/baz.txt); // /foo/bar path.basename(/foo/bar/baz.txt); // baz.txt path.extname(baz.txt); // .txtURL处理const url require(url); const parsed url.parse(https://example.com/path?query123); const myURL new URL(https://example.com);7.3 进程控制函数process对象process.argv; // 命令行参数 process.env.NODE_ENV; // 环境变量 process.cwd(); // 当前工作目录 process.exit(1); // 退出进程子进程const { exec } require(child_process); exec(ls -la, (error, stdout, stderr) { if (error) console.error(error); console.log(stdout); });定时器增强setImmediate(() console.log(Immediate)); process.nextTick(() console.log(Next tick));8. 函数性能优化与调试8.1 性能优化技巧避免不必要的函数创建// 不好的做法 - 每次渲染都创建新函数 function Component() { return button onClick{() console.log(Click)}Click/button; } // 好的做法 - 使用useCallback或类方法 function Component() { const handleClick useCallback(() console.log(Click), []); return button onClick{handleClick}Click/button; }使用记忆化减少重复计算const memoized memoize(expensiveCalculation); memoized(input1); // 计算 memoized(input1); // 从缓存读取批量操作DOM// 不好的做法 - 多次重排 elements.forEach(el el.style.width 100px); // 好的做法 - 使用文档片段 const fragment document.createDocumentFragment(); elements.forEach(el { el.style.width 100px; fragment.appendChild(el); }); document.body.appendChild(fragment);8.2 函数调试技巧console的进阶用法console.time(label); // 要测量的代码 console.timeEnd(label); // 输出执行时间 console.table([{a:1, b:2}, {a:3, b:4}]); // 表格形式输出 console.group(Group); console.log(Message inside group); console.groupEnd();debugger语句function problematicFunction() { debugger; // 执行到这里会暂停 // ... }错误追踪function trackError() { try { // 可能出错的代码 } catch (error) { console.error(Error:, error); console.trace(); // 打印调用栈 } }8.3 函数性能分析performance APIperformance.mark(start); // 要测量的代码 performance.mark(end); performance.measure(measureName, start, end); const measure performance.getEntriesByName(measureName)[0]; console.log(measure.duration); // 执行时间(毫秒)内存分析// 记录初始内存 const initialMemory process.memoryUsage().heapUsed; // 执行代码后 const finalMemory process.memoryUsage().heapUsed; console.log(Memory used: ${finalMemory - initialMemory} bytes);CPU分析const profiler require(v8-profiler-next); profiler.startProfiling(profile1); // 执行要分析的代码 const profile profiler.stopProfiling(profile1); profile.export().pipe(fs.createWriteStream(profile.cpuprofile));9. 函数安全与最佳实践9.1 函数安全注意事项避免eval// 不安全 - 可能执行恶意代码 eval(userInput); // 替代方案 - 使用JSON.parse或Function构造函数 const data JSON.parse(userInput); const func new Function(a, b, return a b);防止原型污染function safeMerge(target, source) { for (const key in source) { if (key ! __proto__ key ! constructor key ! prototype) { target[key] source[key]; } } return target; }输入验证function processInput(input) { if (typeof input ! string) { throw new TypeError(Expected string input); } // 处理输入 }9.2 函数设计最佳实践单一职责原则// 不好的做法 - 函数做太多事情 function processUser(user) { validateUser(user); saveToDatabase(user); sendWelcomeEmail(user); updateAnalytics(user); } // 好的做法 - 拆分函数 function processUser(user) { validateUser(user); persistUser(user); notifyUser(user); trackUser(user); }合理的参数数量// 不好的做法 - 参数太多 function createUser(name, email, password, age, gender, address, phone) {} // 好的做法 - 使用对象参数 function createUser({name, email, password, ...details}) {}明确的返回值// 不好的做法 - 不一致的返回类型 function getUser(id) { if (!id) return false; return {id, name: John}; } // 好的做法 - 一致的返回类型 function getUser(id) { if (!id) return null; return {id, name: John}; }9.3 错误处理策略错误优先回调function asyncOperation(callback) { someAsyncTask((err, result) { if (err) return callback(err); callback(null, processResult(result)); }); }Promise错误处理asyncFunction() .then(result processResult(result)) .catch(error handleError(error)) .finally(() cleanup());async/await错误处理async function run() { try { const result await asyncFunction(); return processResult(result); } catch (error) { handleError(error); } finally { cleanup(); } }10. 现代JavaScript新特性函数10.1 ES6新增函数特性默认参数function greet(name Guest) { console.log(Hello, ${name}!); }剩余参数function sum(...numbers) { return numbers.reduce((acc, num) acc num, 0); }解构参数function printUser({name, age}) { console.log(${name} is ${age} years old); }10.2 ES2017新增函数Object.values/Object.entriesconst obj {a:1, b:2}; Object.values(obj); // [1,2] Object.entries(obj); // [[a,1],[b,2]]字符串填充函数hello.padStart(10, *); // *****hello hello.padEnd(10, *); // hello*****函数参数尾逗号function foo( param1, param2, // 允许尾逗号 ) {}10.3 ES2018新增函数特性异步迭代async function process(array) { for await (const item of array) { await doSomething(item); } }Rest/Spread属性const obj {a:1, b:2, c:3}; const {a, ...rest} obj; // rest {b:2, c:3} const newObj {...obj, d:4}; // {a:1, b:2, c:3, d:4}Promise.finallyfetch(url) .then(response response.json()) .catch(error console.error(error)) .finally(() stopLoading());10.4 ES2019新增函数Array.flat/flatMap[1,[2,[3]]].flat(2); // [1,2,3] [1,2,3].flatMap(x [x, x*2]); // [1,2,2,4,3,6]Object.fromEntriesObject.fromEntries([[a,1],[b,2]]); // {a:1, b:2}字符串trim方法 hello .trimStart(); // hello hello .trimEnd(); // hello10.5 ES2020新增函数可选链操作符const name user?.profile?.name;空值合并运算符const value input ?? default;BigIntconst bigNum BigInt(Number.MAX_SAFE_INTEGER) 1n;动态导入const module await import(/modules/module.js);全局Thisconst global globalThis; // 浏览器中是windowNode中是globalPromise.allSettledPromise.allSettled([promise1, promise2]) .then(results { results.forEach(result { if (result.status fulfilled) console.log(result.value); else console.error(result.reason); }); });String.matchAllconst regexp /t(e)(st(\d?))/g; const str test1test2; const matches [...str.matchAll(regexp)];逻辑赋值运算符a || b; // a a || b a b; // a a b a ?? b; // a a ?? b数字分隔符const billion 1_000_000_000;WeakRef和FinalizationRegistryconst weakRef new WeakRef(targetObject); const registry new FinalizationRegistry(heldValue { console.log(${heldValue} was garbage collected); }); registry.register(targetObject, some value);