JavaScript 核心特性综合实战 —— 从函数到对象的深度应用
(2026年视角 · 中高级进阶 · 强烈建议全部手敲)
下面这套综合实战题目把 JavaScript 最核心、最常被考察的几个特性(函数、闭包、this、原型、对象操作)全部串起来,难度从易到难,适合用来:
- 查漏补缺
- 面试前一周冲刺
- 真正搞懂“函数即对象”这句话的深层含义
实战题目清单(建议按顺序完成)
Level 1:基础函数与闭包暖身(必做)
// 1. 实现一个只能调用一次的函数(once)
function once(fn) {
// 你的实现
}
const log = once(() => console.log("我只会被打印一次"));
log(); // 打印
log(); // 无输出
log(); // 无输出
// 2. 实现一个累加器(使用闭包)
function createCounter() {
// 返回的对象包含三个方法:increment, decrement, value
}
const counter = createCounter();
console.log(counter.value()); // 0
counter.increment();
counter.increment();
console.log(counter.value()); // 2
counter.decrement();
console.log(counter.value()); // 1
Level 2:this 指向地狱 + call/apply/bind 大乱斗
// 3. 下面这段代码输出是什么?如何修改让它正确输出 10, 20, 30?
const obj = {
value: 10,
getValue: function() {
return this.value;
}
};
const fn1 = obj.getValue;
console.log(fn1()); // ?
const fn2 = obj.getValue.bind(obj);
console.log(fn2()); // ?
const fn3 = obj.getValue.call({ value: 30 });
console.log(fn3()); // ?
// 4. 实现一个简易的 bind 方法(不要使用原生的 bind)
Function.prototype.myBind = function(context, ...args) {
// 你的实现
};
function sayHello(greeting, punctuation) {
console.log(`${greeting}, 我是 ${this.name}${punctuation}`);
}
const person = { name: "小明" };
const boundSay = sayHello.myBind(person, "你好");
boundSay("!"); // 你好, 我是 小明!
Level 3:原型链 + 对象操作深度融合
// 5. 实现一个深拷贝(处理循环引用 + 常见特殊类型)
function deepClone(obj, visited = new WeakMap()) {
// 你的实现(要能处理:对象、数组、Date、RegExp、函数、循环引用)
}
// 测试用例
const original = {
a: 1,
b: [2, 3],
c: new Date(),
d: /test/gi,
e: function() { console.log("fn"); },
f: null,
g: undefined,
self: null // 循环引用
};
original.self = original;
const copy = deepClone(original);
console.log(copy === original); // false
console.log(copy.self === copy); // true(循环引用正确处理)
console.log(copy.c instanceof Date); // true
Level 4:终极综合题 —— 实现一个“带记忆的计算属性”对象(Vue computed 简化版)
/**
* 实现一个 createComputedObj 函数
* 它接收一个对象,对象的值可以是普通值或函数(计算属性)
* 返回的对象中,所有计算属性都是惰性求值 + 缓存的
* 当依赖的普通值变化时,相关计算属性缓存失效
*/
const data = createComputedObj({
firstName: "张",
lastName: "三",
fullName() {
return this.firstName + this.lastName;
},
greeting() {
return `你好,${this.fullName}!`;
}
});
console.log(data.fullName); // "张三"
console.log(data.greeting); // "你好,张三!"
// 修改依赖
data.firstName = "李";
console.log(data.fullName); // "李三"(重新计算)
console.log(data.greeting); // "你好,李三!"(greeting 也重新计算)
// 再次访问,不重新计算
console.log(data.fullName); // "李三"(直接从缓存取)
参考答案思路提示(建议先自己做完再看)
- once → 使用闭包 + 标志位(或 WeakMap 存储函数)
- createCounter → 闭包保存 count 私有变量
- this 指向 → 普通函数调用 this 丢失,bind/call 显式绑定
- myBind → 返回新函数 + 拼接参数 + 处理 new 调用情况
- deepClone → 递归 + WeakMap 记录已克隆对象 + 特殊类型单独处理(Date/Date、RegExp、函数可直接返回或深拷贝)
- createComputedObj → 使用 Proxy + 依赖收集(最简版可用 Map 记录依赖关系 + 缓存 Map)
推荐完成顺序 & 时间建议(总计 4~8 小时)
1~2题(闭包基础) 30~60分钟
3~4题(this & bind) 60~90分钟
5题(深拷贝) 90~120分钟
6题(终极综合) 120~180分钟(最有价值)
全部做完后,你会对下面这些核心概念有质的飞跃:
- 函数是一等公民 & 函数即对象
- 闭包的真正用途(私有变量 + 记忆 + 模块化)
- this 动态绑定本质
- 原型链与属性查找机制
- 现代 JS 对象操作(Proxy、WeakMap、Symbol 等)
如果你已经做完某几道题,欢迎贴出你的代码,我帮你 review 优化!
或者直接说“我卡在第X题”,我给你更细致的思路引导~