JavaScript 核心特性综合实战 —— 从函数到对象的深度应用
(2026 年视角,偏向中高级实战 + 面试高频考察点)
下面通过 8 个递进式综合案例,把函数、闭包、this、原型、对象操作、ES6+ 新特性、异步、模块等核心概念串联起来。每个案例都尽量贴近真实项目中会遇到的写法和思考。
案例 1:函数柯里化 + 偏函数 + 组合(函数式编程基础)
// 通用柯里化工具(支持占位符 _ )
const _ = Symbol('placeholder');
function curry(fn, ...initialArgs) {
return function curried(...args) {
const allArgs = [...initialArgs, ...args];
const placeholders = allArgs.filter(a => a === _).length;
if (placeholders === 0 && allArgs.length >= fn.length) {
return fn(...allArgs);
}
return curry(fn, ...allArgs);
};
}
// 使用示例
const format = (date, tpl) => {
const d = new Date(date);
return tpl
.replace('YYYY', d.getFullYear())
.replace('MM', String(d.getMonth() + 1).padStart(2, '0'))
.replace('DD', String(d.getDate()).padStart(2, '0'));
};
const formatUS = curry(format, _, 'MM/DD/YYYY');
console.log(formatUS(new Date())); // "02/25/2026"
console.log(formatUS(_, 'YYYY-MM-DD')(new Date())); // "2026-02-25"
考察点:
- 函数柯里化实现
- 偏函数(partial application)
- Symbol 作为占位符
- 函数作为一等公民
案例 2:闭包 + 私有成员 + 模块模式(2026 仍在大量使用)
const createCounter = (initial = 0) => {
let count = initial;
return {
increment: (step = 1) => {
count += step;
return count;
},
decrement: (step = 1) => {
count -= step;
return count;
},
reset: () => {
count = initial;
return count;
},
get value() { return count; }
};
};
const counter = createCounter(100);
console.log(counter.increment()); // 101
console.log(counter.increment(5)); // 106
console.log(counter.value); // 106
counter.reset();
console.log(counter.value); // 100
现代替代写法(使用 # 私有字段)
class Counter {
#count;
constructor(initial = 0) {
this.#count = initial;
}
increment(step = 1) { this.#count += step; return this.#count; }
get value() { return this.#count; }
}
案例 3:this 绑定陷阱 + 多种解决方案对比
class User {
constructor(name) {
this.name = name;
}
// 问题写法
greetDelay_bad() {
setTimeout(function() {
console.log(`Hi, I'm ${this.name}`); // this → window / undefined
}, 1000);
}
// 解决方案 1:箭头函数(最常用)
greetDelay_arrow() {
setTimeout(() => {
console.log(`Hi, I'm ${this.name}`);
}, 1000);
}
// 解决方案 2:bind
greetDelay_bind() {
setTimeout(function() {
console.log(`Hi, I'm ${this.name}`);
}.bind(this), 1000);
}
// 解决方案 3:保存 this
greetDelay_that() {
const that = this;
setTimeout(function() {
console.log(`Hi, I'm ${that.name}`);
}, 1000);
}
}
2026 推荐优先级:箭头函数 > bind > that
案例 4:原型链 + 继承 + 现代 class + super
class Animal {
constructor(name) {
this.name = name;
}
speak() {
return `${this.name} makes a sound.`;
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name);
this.breed = breed;
}
speak() {
return `${super.speak()} Specifically, a ${this.breed} woofs!`;
}
static createFromJSON(json) {
const data = JSON.parse(json);
return new Dog(data.name, data.breed);
}
}
const dog = Dog.createFromJSON('{"name":"Max","breed":"Golden Retriever"}');
console.log(dog.speak());
考察点:
- extends / super
- static 方法
- 方法覆盖 + 调用父类
案例 5:对象深拷贝 + 性能对比(真实面试题)
// 方法 1:JSON(最简单,但有局限)
function deepCopyJSON(obj) {
return JSON.parse(JSON.stringify(obj));
}
// 方法 2:结构化克隆(浏览器推荐,性能最好,支持更多类型)
function deepCopyStructured(obj) {
return structuredClone(obj); // Chrome 98+、Node 17+、Deno 全支持
}
// 方法 3:递归(最灵活,可自定义行为)
function deepCopyRecursive(obj, visited = new WeakMap()) {
if (obj === null || typeof obj !== 'object') return obj;
if (visited.has(obj)) return visited.get(obj);
const copy = Array.isArray(obj) ? [] : {};
visited.set(obj, copy);
for (const key in obj) {
copy[key] = deepCopyRecursive(obj[key], visited);
}
return copy;
}
性能排序(大对象):structuredClone > JSON > 递归
案例 6:Proxy + Reflect(响应式核心原理)
function reactive(obj) {
return new Proxy(obj, {
set(target, key, value, receiver) {
console.log(`设置 ${String(key)} = ${value}`);
return Reflect.set(target, key, value, receiver);
},
get(target, key, receiver) {
const value = Reflect.get(target, key, receiver);
console.log(`读取 ${String(key)} → ${value}`);
return value;
}
});
}
const state = reactive({ count: 0, user: { name: "重阳" } });
state.count++; // 触发 set
console.log(state.user.name); // 触发 get
真实应用:Vue 3 reactivity、MobX、Immer 等底层原理
案例 7:异步函数 + Promise + async/await + 错误处理
async function fetchWithRetry(url, retries = 3) {
for (let i = 0; i < retries; i++) {
try {
const response = await fetch(url);
if (!response.ok) throw new Error(`HTTP ${response.status}`);
return await response.json();
} catch (err) {
if (i === retries - 1) throw err;
console.warn(`第 ${i + 1} 次失败,重试...`);
await new Promise(r => setTimeout(r, 1000 * (i + 1)));
}
}
}
// 使用
(async () => {
try {
const data = await fetchWithRetry('https://api.example.com/data');
console.log(data);
} catch (err) {
console.error('全部重试失败:', err);
}
})();
案例 8:综合实战 —— 实现一个简易的 EventEmitter(观察者模式)
class EventEmitter {
#events = new Map();
on(event, listener) {
if (!this.#events.has(event)) {
this.#events.set(event, new Set());
}
this.#events.get(event).add(listener);
return () => this.off(event, listener); // 返回取消函数
}
off(event, listener) {
const listeners = this.#events.get(event);
if (listeners) {
listeners.delete(listener);
if (listeners.size === 0) this.#events.delete(event);
}
}
emit(event, ...args) {
const listeners = this.#events.get(event);
if (listeners) {
for (const listener of listeners) {
try {
listener(...args);
} catch (err) {
console.error(`事件 ${event} 监听器执行出错:`, err);
}
}
}
}
once(event, listener) {
const wrapper = (...args) => {
listener(...args);
this.off(event, wrapper);
};
return this.on(event, wrapper);
}
}
// 使用示例
const emitter = new EventEmitter();
emitter.on('user:login', user => console.log(`${user.name} 登录了`));
emitter.once('user:logout', () => console.log('用户登出(只触发一次)'));
emitter.emit('user:login', { name: "重阳" });
emitter.emit('user:logout');
emitter.emit('user:logout'); // 不会再触发
这些案例把函数、闭包、this、原型、对象、Proxy、异步、模块化等核心特性做了较为完整的串联。
如果你想针对其中任意一个案例深入(比如加类型、性能优化、错误边界、测试用例、真实业务场景改造),或者想增加更多 2026 年新特性(Temporal、Pipeline Operator、Records & Tuples 等),随时告诉我~