JavaScript 核心特性综合实战 —— 从函数到对象的深度应用

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 等),随时告诉我~

文章已创建 4791

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部