// 函数声明(会提升)
function add(a, b) {
return a + b;
}
// 函数表达式(不会提升)
const multiply = function (a, b) {
return a * b;
};
// 箭头函数表达式(ES6+)
const divide = (a, b) => a / b;
// 立即执行函数表达式(IIFE)
(function () {
console.log("立即执行");
})();
// 命名函数表达式
const factorial = function fact(n) {
return n <= 1 ? 1 : n * fact(n - 1);
};
// 基本参数
function greet(name, greeting = "Hello") {
// 默认参数
console.log(`${greeting}, ${name}!`);
}
// 剩余参数(Rest parameters)
function sum(...numbers) {
return numbers.reduce((acc, curr) => acc + curr, 0);
}
console.log(sum(1, 2, 3, 4, 5)); // 15
// 参数解构
function printUser({ name, age, city = "未知" }) {
console.log(`姓名: ${name}, 年龄: ${age}, 城市: ${city}`);
}
printUser({ name: "张三", age: 25 }); // 姓名: 张三, 年龄: 25, 城市: 未知
// 参数列表解构
function coordinates([x, y]) {
console.log(`坐标: (${x}, ${y})`);
}
coordinates([10, 20]); // 坐标: (10, 20)
// 返回单个值
function getFullName(firstName, lastName) {
return `${firstName} ${lastName}`;
}
// 返回多个值(通过对象或数组)
function getCoordinates() {
return { x: 10, y: 20 }; // 返回对象
// 或 return [10, 20]; // 返回数组
}
// 返回函数(闭包)
function createCounter() {
let count = 0;
return function () {
return ++count;
};
}
// 返回 Promise
async function fetchData() {
return await fetch("/api/data").then(res => res.json());
}
function createUser(name, age = 18, city = "北京") {
return { name, age, city };
}
console.log(createUser("张三")); // {name: '张三', age: 18, city: '北京'}
console.log(createUser("李四", 25)); // {name: '李四', age: 25, city: '北京'}
function join(separator, ...strings) {
return strings.join(separator);
}
console.log(join("-", "a", "b", "c")); // "a-b-c"
// 对象解构
function drawChart({ size = "big", coords = { x: 0, y: 0 }, radius = 25 } = {}) {
console.log(size, coords, radius);
}
drawChart({ coords: { x: 18, y: 30 }, radius: 30 });
// 数组解构
function tail([first, ...rest]) {
return rest;
}
console.log(tail([1, 2, 3, 4])); // [2, 3, 4]
const obj = {
// ES5
oldWay: function () {
return "old";
},
// ES6+ 简写
newWay() {
return "new";
},
// 计算属性名方法
["computed" + "Method"]() {
return "computed";
},
// 异步方法
async fetchData() {
const response = await fetch("/api/data");
return response.json();
},
// 生成器方法
*generator() {
yield 1;
yield 2;
},
};
// 基本语法
const add = (a, b) => a + b;
// 单个参数可省略括号
const square = x => x * x;
// 无参数需要括号
const getRandom = () => Math.random();
// 多行语句需要大括号
const complexOperation = (a, b) => {
const sum = a + b;
const product = a * b;
return { sum, product };
};
// 返回对象字面量需要括号
const createUser = (name, age) => ({ name, age });
// 箭头函数特点
const obj = {
value: 10,
regularFunc: function () {
console.log(this.value); // 10 - this 指向 obj
},
arrowFunc: () => {
console.log(this.value); // undefined - this 继承自外层作用域
},
};
// 不能作为构造函数
const Person = name => {
this.name = name; // 错误:箭头函数不能作为构造函数
};
// new Person(); // TypeError
// 没有 arguments 对象
const showArgs = (...args) => {
console.log(args); // 使用剩余参数
// console.log(arguments); // 错误:arguments 未定义
};
// 生成器函数声明
function* numberGenerator() {
let num = 1;
while (true) {
yield num++;
}
}
// 生成器函数表达式
const genFunc = function* () {
yield 1;
yield 2;
yield 3;
};
// 生成器方法
const obj = {
*generatorMethod() {
yield "value";
},
};
// 异步生成器函数
async function* asyncGenerator() {
yield await Promise.resolve(1);
yield await Promise.resolve(2);
}
// 异步函数声明
async function fetchUser(id) {
const response = await fetch(`/api/users/${id}`);
return await response.json();
}
// 异步函数表达式
const fetchData = async function (url) {
const response = await fetch(url);
return response.json();
};
// 异步箭头函数
const processData = async data => {
const result = await transform(data);
return result;
};
// 异步方法
class ApiClient {
async get(endpoint) {
const response = await fetch(endpoint);
return response.json();
}
}
// 全局作用域
const globalVar = "全局变量";
function outer() {
// 函数作用域
const outerVar = "外部变量";
function inner() {
// 块级作用域(ES6+)
let blockVar = "块级变量";
const innerVar = "内部变量";
console.log(globalVar); // 可访问
console.log(outerVar); // 可访问
console.log(innerVar); // 可访问
console.log(blockVar); // 可访问
}
inner();
// console.log(innerVar); // 错误:不可访问
// console.log(blockVar); // 错误:不可访问
}
// 变量提升
console.log(hoisted); // undefined
var hoisted = "已提升";
console.log(letHoisted); // ReferenceError
let letHoisted = "不会提升";
// 基本闭包
function createCounter() {
let count = 0; // 私有变量
return {
increment() {
count++;
return count;
},
decrement() {
count--;
return count;
},
getValue() {
return count;
},
};
}
const counter = createCounter();
console.log(counter.increment()); // 1
console.log(counter.increment()); // 2
console.log(counter.getValue()); // 2
// 循环中的闭包(经典问题)
// 答:var 只有一个 i,定时器回调执行时循环已结束,i 变成 3,所以打印 3 次 3。
for (var i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i); // 输出3次 3
}, 100);
}
// 解决方案1:使用IIFE
for (var i = 0; i < 3; i++) {
(function (j) {
setTimeout(function () {
console.log(j); // 0, 1, 2
}, 100);
})(i);
}
// 解决方案2:使用let(块级作用域)
for (let i = 0; i < 3; i++) {
setTimeout(function () {
console.log(i); // 0, 1, 2
}, 100);
}
// 模块模式
const calculator = (function () {
let memory = 0;
function add(a, b) {
return a + b;
}
function subtract(a, b) {
return a - b;
}
function store(value) {
memory = value;
}
function recall() {
return memory;
}
// 只暴露公共接口
return {
add,
subtract,
store,
recall,
};
})();
console.log(calculator.add(5, 3)); // 8
calculator.store(10);
console.log(calculator.recall()); // 10
// this 的四种绑定规则
// 1. 默认绑定(非严格模式)
function showDefault() {
console.log(this); // 浏览器中:Window,Node.js中:global
}
showDefault();
// 2. 隐式绑定
const obj = {
name: "张三",
sayHello() {
console.log(`Hello, ${this.name}`);
},
};
obj.sayHello(); // Hello, 张三
// 3. 显式绑定
function greet(greeting) {
console.log(`${greeting}, ${this.name}`);
}
const person = { name: "李四" };
greet.call(person, "Hi"); // Hi, 李四
greet.apply(person, ["Hello"]); // Hello, 李四
const boundGreet = greet.bind(person, "Welcome");
boundGreet(); // Welcome, 李四
// 4. new 绑定
function Person(name) {
this.name = name;
}
const john = new Person("John");
console.log(john.name); // John
// 箭头函数的 this
// 解释:
// 在常规函数 getValue 中,this 指向调用该函数的对象 arrowObj,因此返回了 42。
// 在箭头函数 getValueArrow 中,this 不绑定到调用它的对象,而是继承自定义函数创建时的上下文(在这种情况下是全局对象或 undefined),因此返回了 undefined。
const arrowObj = {
value: 42,
getValue: function () {
return this.value; // 42 - 常规函数
},
getValueArrow: () => {
return this.value; // undefined - 箭头函数
},
};
// 基本柯里化
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));
};
}
};
}
// 使用示例
function addThree(a, b, c) {
return a + b + c;
}
const curriedAdd = curry(addThree);
console.log(curriedAdd(1)(2)(3)); // 6
console.log(curriedAdd(1, 2)(3)); // 6
console.log(curriedAdd(1)(2, 3)); // 6
// 实用柯里化示例
const multiply = a => b => a * b;
const double = multiply(2);
const triple = multiply(3);
console.log(double(5)); // 10
console.log(triple(5)); // 15
// 柯里化HTTP请求
const createRequest = method => url => data => {
return fetch(url, {
method,
body: JSON.stringify(data),
});
};
const post = createRequest("POST");
const postToUsers = post("/api/users");
postToUsers({ name: "张三" });
// 基本组合
const compose =
(...fns) =>
x =>
fns.reduceRight((acc, fn) => fn(acc), x);
const pipe =
(...fns) =>
x =>
fns.reduce((acc, fn) => fn(acc), x);
// 使用示例
const add = x => x + 1;
const multiply = x => x * 2;
const square = x => x * x;
const addThenMultiply = compose(multiply, add);
console.log(addThenMultiply(5)); // (5 + 1) * 2 = 12
const complex = pipe(add, multiply, square);
console.log(complex(5)); // ((5 + 1) * 2)^2 = 144
// 实用组合示例
const users = [
{ name: "张三", age: 25, active: true },
{ name: "李四", age: 30, active: false },
{ name: "王五", age: 28, active: true },
];
const isActive = user => user.active;
const getName = user => user.name;
const uppercase = str => str.toUpperCase();
const getActiveUserNames = pipe(
users => users.filter(isActive),
users => users.map(getName),
names => names.map(uppercase)
);
console.log(getActiveUserNames(users)); // ['张三', '王五']
// 返回函数的高阶函数
function withLogger(fn) {
return function (...args) {
console.log(`调用函数 ${fn.name},参数:`, args);
const result = fn.apply(this, args);
console.log(`函数 ${fn.name} 返回值:`, result);
return result;
};
}
// 使用示例
const add = (a, b) => a + b;
const loggedAdd = withLogger(add);
loggedAdd(2, 3); // 日志输出,返回5
// 接收函数作为参数的高阶函数
function repeat(n, fn) {
for (let i = 0; i < n; i++) {
fn(i);
}
}
repeat(5, console.log); // 输出 0 1 2 3 4
// 数组高阶函数
const numbers = [1, 2, 3, 4, 5];
// map
const doubled = numbers.map(x => x * 2); // [2, 4, 6, 8, 10]
// filter
const evens = numbers.filter(x => x % 2 === 0); // [2, 4]
// reduce
const sum = numbers.reduce((acc, x) => acc + x, 0); // 15
// 自定义高阶函数
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 expensiveCalc = memoize(function (n) {
console.log("计算中...");
return n * n;
});
console.log(expensiveCalc(5)); // 计算中... 25
console.log(expensiveCalc(5)); // 25 (从缓存读取)
// 纯函数示例
function pureAdd(a, b) {
return a + b; // 相同输入总是返回相同输出,无副作用
}
// 不纯的函数示例
let counter = 0;
function impureAdd(a) {
counter++; // 副作用:修改外部状态
return a + counter; // 相同输入可能返回不同输出
}
// 纯函数的优点
function pureTax(price, rate) {
return price * rate; // 可缓存、可测试、可并行
}
// 数据不可变性
const numbers = [1, 2, 3];
// 不纯的方式
numbers.push(4); // 修改原数组
// 纯的方式
const newNumbers = [...numbers, 4]; // 创建新数组
// 常用函数式工具函数
// 偏函数(部分应用)
const partial =
(fn, ...fixedArgs) =>
(...restArgs) =>
fn(...fixedArgs, ...restArgs);
function greet(greeting, name) {
return `${greeting}, ${name}!`;
}
const sayHello = partial(greet, "Hello");
console.log(sayHello("张三")); // Hello, 张三!
// 防抖
function debounce(fn, delay) {
let timeoutId;
return function (...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
fn.apply(this, args);
}, delay);
};
}
// 节流
function throttle(fn, limit) {
let inThrottle;
return function (...args) {
if (!inThrottle) {
fn.apply(this, args);
inThrottle = true;
setTimeout(() => (inThrottle = false), limit);
}
};
}
// 记忆化
function memoizeWithLimit(fn, limit = 100) {
const cache = new Map();
const keys = [];
return function (...args) {
const key = JSON.stringify(args);
if (cache.has(key)) {
// 移动到最后(最近使用)
const index = keys.indexOf(key);
keys.splice(index, 1);
keys.push(key);
return cache.get(key);
}
const result = fn.apply(this, args);
cache.set(key, result);
keys.push(key);
// 限制缓存大小
if (keys.length > limit) {
const oldestKey = keys.shift();
cache.delete(oldestKey);
}
return result;
};
}
// Maybe 函子
class Maybe {
constructor(value) {
this._value = value;
}
static of(value) {
return new Maybe(value);
}
isNothing() {
return this._value === null || this._value === undefined;
}
map(fn) {
if (this.isNothing()) {
return Maybe.of(null);
}
return Maybe.of(fn(this._value));
}
chain(fn) {
return this.map(fn).join();
}
join() {
return this._value;
}
getOrElse(defaultValue) {
return this.isNothing() ? defaultValue : this._value;
}
}
// 使用示例
const user = { name: "张三", address: { city: "北京" } };
const maybeUser = Maybe.of(user);
const city = maybeUser
.map(u => u.address)
.map(addr => addr.city)
.getOrElse("未知城市");
console.log(city); // 北京
// Either 函子
class Either {
constructor(left, right) {
this.left = left;
this.right = right;
}
static Left(value) {
return new Either(value, null);
}
static Right(value) {
return new Either(null, value);
}
map(fn) {
return this.right !== null ? Either.Right(fn(this.right)) : Either.Left(this.left);
}
chain(fn) {
return this.right !== null ? fn(this.right) : this;
}
fold(leftFn, rightFn) {
return this.right !== null ? rightFn(this.right) : leftFn(this.left);
}
}
// 使用示例
function parseJSON(json) {
try {
return Either.Right(JSON.parse(json));
} catch (error) {
return Either.Left(error.message);
}
}
parseJSON('{"name": "张三"}').fold(
error => console.error("解析失败:", error),
data => console.log("解析成功:", data)
);
// 动态创建函数
const add = new Function("a", "b", "return a + b");
console.log(add(2, 3)); // 5
// 复杂动态函数
const operation = new Function(
"x",
"y",
`
const sum = x + y;
const product = x * y;
return { sum, product };
`
);
console.log(operation(3, 4)); // {sum: 7, product: 12}
// 注意:存在安全风险,谨慎使用
// 函数长度属性
function example(a, b, c) {}
console.log(example.length); // 3
// 函数名称属性
function namedFunction() {}
console.log(namedFunction.name); // "namedFunction"
const anonymous = function () {};
console.log(anonymous.name); // "anonymous" (ES6+)
const arrow = () => {};
console.log(arrow.name); // "arrow" (ES6+)
// 自定义函数属性
function getUniqueId() {
if (!getUniqueId.counter) {
getUniqueId.counter = 0;
}
return ++getUniqueId.counter;
}
console.log(getUniqueId()); // 1
console.log(getUniqueId()); // 2
console.log(getUniqueId.counter); // 2
// 获取函数源码
function exampleFunc() {
return "hello";
}
console.log(exampleFunc.toString());
// "function exampleFunc() {
// return 'hello';
// }"
// 修改函数行为
function original() {
console.log("原始函数");
}
const originalRef = original;
original = function () {
console.log("包装前");
originalRef();
console.log("包装后");
};
original(); // 包装前 -> 原始函数 -> 包装后
// Proxy 包装函数
function createTraceable(fn) {
return new Proxy(fn, {
apply(target, thisArg, args) {
console.log(`调用 ${target.name},参数:`, args);
const result = Reflect.apply(target, thisArg, args);
console.log(`结果:`, result);
return result;
},
});
}
const tracedAdd = createTraceable(function add(a, b) {
return a + b;
});
tracedAdd(2, 3); // 调用 add,参数: [2, 3] -> 结果: 5
// 1. 避免重复创建函数
// 不好
function processItems(items) {
items.forEach(item => {
const processor = () => {
/* 处理逻辑 */
};
processor(item);
});
}
// 好
function processor(item) {
/* 处理逻辑 */
}
function processItems(items) {
items.forEach(processor);
}
// 2. 尾调用优化
// 普通递归(可能导致栈溢出)
function factorial(n) {
if (n <= 1) return 1;
return n * factorial(n - 1); // 不是尾调用
}
// 尾递归优化
function factorialTail(n, acc = 1) {
if (n <= 1) return acc;
return factorialTail(n - 1, n * acc); // 尾调用
}
// 3. 函数内联
// 小函数自动内联
function add(a, b) {
return a + b;
}
function calculate() {
const result = add(5, 3); // 可能被内联为 const result = 5 + 3;
return result;
}
// Try-Catch 包装器
function tryCatch(fn, errorHandler = console.error) {
return function (...args) {
try {
return fn.apply(this, args);
} catch (error) {
errorHandler(error);
return null;
}
};
}
// 异步错误处理
async function asyncTryCatch(promise, fallbackValue = null) {
try {
return await promise;
} catch (error) {
console.error("异步操作失败:", error);
return fallbackValue;
}
}
// 结果类型包装
class Result {
constructor(success, value, error) {
this.success = success;
this.value = value;
this.error = error;
}
static success(value) {
return new Result(true, value, null);
}
static failure(error) {
return new Result(false, null, error);
}
map(fn) {
return this.success ? Result.success(fn(this.value)) : this;
}
getOrElse(defaultValue) {
return this.success ? this.value : defaultValue;
}
}
function safeOperation(fn) {
return function (...args) {
try {
return Result.success(fn.apply(this, args));
} catch (error) {
return Result.failure(error);
}
};
}
// 依赖注入
function createUserService(userRepository = defaultUserRepository) {
return {
async getUser(id) {
return await userRepository.findById(id);
},
async createUser(userData) {
return await userRepository.create(userData);
},
};
}
// 纯函数易于测试
function calculateDiscount(price, discountRate) {
return price * (1 - discountRate);
}
// 可组合的函数
const validationRules = {
isEmail: value => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value),
isRequired: value => value != null && value.trim() !== "",
minLength: length => value => value.length >= length,
};
function validate(value, rules) {
return rules.every(rule => rule(value));
}