JavaScript函数是一段可重复使用的代码块,用于执行特定任务。函数通过
function关键字定义,可以接收参数、执行操作并返回结果。函数可以被定义一次,然后在程序中多次调用,从而实现代码的复用和模块化编程。本文将带来JavaScript基础到高阶实战分享!函数定义
1. 传统定义方式
// 1. 函数声明(存在提升)function sum(a, b) {return a + b;}// 2. 函数表达式const multiply = function(a, b) {return a * b;};// 3. 构造函数(不推荐)const div = new Function('a', 'b', 'return a / b');
2. 现代ES6+语法
// 4. 箭头函数(无this/arguments)const pow = (base, exponent) => base ** exponent;// 5. 简写方法语法const calculator = {sqrt(x) {return Math.sqrt(x);}};// 6. 生成器函数function* idGenerator() {let id = 1;while(true) yield id++;}// 7. Async函数async function fetchData(url) {const res = await fetch(url);return res.json();}
3. 关键差异对比
| 特性 | 函数声明 | 函数表达式 | 箭头函数 |
|---|---|---|---|
| 提升 | ✅ | ❌ | ❌ |
| 自有this | ✅ | ✅ | ❌ |
| arguments对象 | ✅ | ✅ | ❌ |
| 构造函数 | ✅ | ✅ | ❌ |
| 原型属性 | ✅ | ✅ | ❌ |
作用域与闭包
1. 作用域链解析
function outer() {const outerVar = '外层';function inner() {const innerVar = '内层';console.log(outerVar); // 访问外层作用域}return inner;}const closure = outer();closure(); // "外层" (闭包保持outerVar引用)
2. 闭包
实现私有变量
function createCounter() {let count = 0;return {increment() { count++ },get() { return count },reset() { count = 0 }};}const counter = createCounter();counter.increment();console.log(counter.get()); // 1
记忆化缓存
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(...args);cache.set(key, result);return result;};}const memoizedFib = memoize(fibonacci);
3. 内存泄漏防范
// 错误示例:DOM元素引用未释放function init() {const element = document.getElementById('bigData');element.addEventListener('click', () => {console.log(element.id); // 闭包保留element引用});}// 正确做法:弱引用function safeInit() {const element = document.getElementById('bigData');const weakRef = new WeakRef(element);element.addEventListener('click', () => {const el = weakRef.deref();if (el) console.log(el.id);});}
this的5种绑定规则
1. 绑定规则详解
// 1. 默认绑定(非严格模式)function showThis() {console.log(this); // window/global}// 2. 隐式绑定const obj = {value: 42,getValue() {return this.value;}};// 3. 显式绑定function logThis() {console.log(this);}const boundFunc = logThis.bind({ name: '绑定的this' });// 4. new绑定function Person(name) {this.name = name;}const person = new Person('Alice');// 5. 箭头函数(继承外层this)const outerThis = this;const arrowFunc = () => {console.log(this === outerThis); // true};
2. 常见问题解决方案
// 回调函数丢失this问题class Timer {constructor() {this.seconds = 0;// 使用箭头函数保留thissetInterval(() => {this.seconds++;}, 1000);}}// 多层嵌套this访问const deepObj = {level1: {level2: {method() {// 使用箭头函数维持this指向const helper = () => {console.log(this); // 指向level2对象};helper();}}}};
高阶函数与函数式编程
1. 高阶函数应用
// 函数组合const compose = (...fns) =>(value) => fns.reduceRight((acc, fn) => fn(acc), value);const add5 = x => x + 5;const double = x => x * 2;const process = compose(double, add5);console.log(process(10)); // (10+5)*2=30// 柯里化实现function curry(fn) {return function curried(...args) {if (args.length >= fn.length) {return fn.apply(this, args);} else {return (...args2) => curried(...args, ...args2);}};}const curriedSum = curry((a, b, c) => a + b + c);console.log(curriedSum(1)(2)(3)); // 6
2. 函数式编程实践
// 不可变数据转换const users = [{ id: 1, name: 'Alice', age: 28 },{ id: 2, name: 'Bob', age: 35 }];// 纯函数处理const getAdults = users =>users.filter(user => user.age >= 18).map(({ id, name }) => ({ id, name }));// 管道操作(ES2023)const result = users|> filter(_, u => u.age > 30)|> map(_, u => ({ ...u, status: 'vip' }));
ES6+ 函数增强特性
1. 参数处理新语法
// 默认参数function createUser(name, { age = 18, role = 'user' } = {}) {return { name, age, role };}// 剩余参数function sumAll(...numbers) {return numbers.reduce((acc, n) => acc + n, 0);}// 参数解构function draw({ x = 0, y = 0, color = 'black' }) {console.log(`在(${x},${y})绘制${color}`);}
2. 元编程能力
// 函数元属性function demo(a, b) {console.log(demo.name); // "demo"console.log(demo.length); // 2}// Reflect APIconst handler = {apply(target, thisArg, args) {console.log(`调用函数并传入参数: ${args}`);return Reflect.apply(...arguments);}};const proxiedFunc = new Proxy(sum, handler);proxiedFunc(2, 3); // 输出日志并返回5
性能优化与调试技巧
1. 函数性能优化
// 避免重复创建函数// 错误示例elements.forEach(element => {element.addEventListener('click', () => {// 每次循环都创建新函数});});// 优化方案const handler = function(event) {// 统一处理逻辑};elements.forEach(element => {element.addEventListener('click', handler);});// 尾调用优化(TCO)function factorial(n, acc = 1) {if (n <= 1) return acc;return factorial(n - 1, n * acc); // 尾递归形式}
2. 调试技巧
总结// 函数断点调试function complexCalculation() {debugger; // 自动暂停执行// ...}// 性能分析console.time('heavyTask');heavyTask();console.timeEnd('heavyTask');// 函数调用追踪function trackCalls(fn) {let count = 0;return function(...args) {count++;console.log(`函数第${count}次调用`);return fn(...args);};}
-
1.优先使用箭头函数:处理异步回调和需要保持this的场景
-
2.合理使用闭包:注意内存管理,必要时使用WeakMap
-
3.避免过度嵌套:使用函数组合替代深层嵌套
-
4.函数单一职责:每个函数只完成一个明确任务
-
5.性能敏感区优化:避免在循环内创建函数
-
6.严格模式启用:'use strict' 避免隐式错误
-
7.全面类型检查:使用TypeScript增强函数可靠性
![]() |
Austin Liu 刘恒辉
Project Manager and Software Designer E-Mail:lzhdim@163.com Blog:https://lzhdim.cnblogs.com 欢迎收藏和转载此博客中的博文,但是请注明出处,给笔者一个与大家交流的空间。谢谢大家。 |




浙公网安备 33010602011771号