logo

面试必刷!最全手写JS题深度解析

作者:c4t2025.09.19 12:48浏览量:0

简介:手写JS题是前端面试的核心环节,涵盖基础语法、函数、对象、异步等关键知识点。本文系统整理高频手写题,提供解题思路与代码实现,助力开发者高效备考。

面试中最全的手写JS题:从基础到进阶的终极指南

在前端开发面试中,手写JavaScript代码题是考察候选人核心能力的关键环节。无论是基础语法、函数实现,还是对象操作、异步处理,面试官都会通过手写题检验候选人对JS本质的理解。本文将系统梳理面试中最常见的手写JS题,涵盖从基础到进阶的完整知识体系,并提供解题思路与代码实现,帮助开发者高效备考。

一、基础语法与变量操作

1. 变量类型判断

题目:实现一个函数,判断输入值的类型(如'number''string''boolean'等)。
解析
JavaScript中,typeof运算符可以返回基本类型,但对于null和引用类型(如ArrayDate)的判断不够精确。需结合Object.prototype.toString.call()实现更全面的类型判断。
代码实现

  1. function getType(value) {
  2. return Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
  3. }
  4. // 测试
  5. console.log(getType(123)); // 'number'
  6. console.log(getType([])); // 'array'
  7. console.log(getType(null)); // 'null'

2. 深拷贝与浅拷贝

题目:实现一个深拷贝函数,支持对象、数组、日期等复杂类型的复制。
解析
浅拷贝仅复制第一层属性,深拷贝需递归处理所有嵌套对象。需注意特殊类型(如DateRegExp)的单独处理。
代码实现

  1. function deepClone(value) {
  2. if (value === null || typeof value !== 'object') return value;
  3. if (value instanceof Date) return new Date(value);
  4. if (value instanceof RegExp) return new RegExp(value);
  5. const clone = Array.isArray(value) ? [] : {};
  6. for (const key in value) {
  7. if (value.hasOwnProperty(key)) {
  8. clone[key] = deepClone(value[key]);
  9. }
  10. }
  11. return clone;
  12. }
  13. // 测试
  14. const obj = { a: 1, b: { c: 2 }, d: new Date() };
  15. const clonedObj = deepClone(obj);
  16. console.log(clonedObj.b.c === obj.b.c); // false

二、函数与高阶函数

1. 柯里化(Currying)

题目:实现一个柯里化函数,将多参数函数转换为单参数函数的嵌套调用。
解析
柯里化的核心是每次接收一个参数,并返回新函数,直到所有参数收集完毕。需处理剩余参数的传递。
代码实现

  1. function curry(fn) {
  2. return function curried(...args) {
  3. if (args.length >= fn.length) {
  4. return fn.apply(this, args);
  5. } else {
  6. return function(...args2) {
  7. return curried.apply(this, args.concat(args2));
  8. }
  9. }
  10. };
  11. }
  12. // 测试
  13. const sum = (a, b, c) => a + b + c;
  14. const curriedSum = curry(sum);
  15. console.log(curriedSum(1)(2)(3)); // 6

2. 防抖与节流

题目:实现防抖(debounce)和节流(throttle)函数,控制高频事件的触发频率。
解析

  • 防抖:事件触发后,等待一段时间再执行,若期间再次触发则重新计时。
  • 节流:固定时间间隔内只执行一次,无论触发多少次。
    代码实现
    ```javascript
    // 防抖
    function debounce(fn, delay) {
    let timer = null;
    return function(…args) {
    clearTimeout(timer);
    timer = setTimeout(() => fn.apply(this, args), delay);
    };
    }

// 节流
function throttle(fn, delay) {
let lastTime = 0;
return function(…args) {
const now = Date.now();
if (now - lastTime >= delay) {
fn.apply(this, args);
lastTime = now;
}
};
}

  1. ## 三、对象与原型链
  2. ### 1. 实现`new`操作符
  3. **题目**:模拟`new`操作符的逻辑,创建一个对象并调用构造函数。
  4. **解析**:
  5. `new`操作符的执行步骤:
  6. 1. 创建新对象,继承构造函数的`prototype`
  7. 2. 调用构造函数,绑定`this`到新对象。
  8. 3. 返回新对象(若构造函数无显式返回,则返回新对象)。
  9. **代码实现**:
  10. ```javascript
  11. function myNew(Constructor, ...args) {
  12. const obj = Object.create(Constructor.prototype);
  13. const result = Constructor.apply(obj, args);
  14. return result instanceof Object ? result : obj;
  15. }
  16. // 测试
  17. function Person(name) {
  18. this.name = name;
  19. }
  20. const person = myNew(Person, 'Alice');
  21. console.log(person.name); // 'Alice'

2. 实现instanceof

题目:模拟instanceof操作符,判断对象是否为构造函数的实例。
解析
通过遍历对象的原型链,检查是否与构造函数的prototype匹配。
代码实现

  1. function myInstanceof(obj, Constructor) {
  2. let proto = Object.getPrototypeOf(obj);
  3. while (proto) {
  4. if (proto === Constructor.prototype) return true;
  5. proto = Object.getPrototypeOf(proto);
  6. }
  7. return false;
  8. }
  9. // 测试
  10. console.log(myInstanceof([], Array)); // true

四、异步编程与Promise

1. 实现Promise

题目:实现一个简化版的Promise,支持thenresolvereject
解析
Promise的核心是状态管理(pendingfulfilledrejected)和异步链式调用。
代码实现

  1. class MyPromise {
  2. constructor(executor) {
  3. this.state = 'pending';
  4. this.value = null;
  5. this.callbacks = [];
  6. const resolve = (value) => {
  7. if (this.state === 'pending') {
  8. this.state = 'fulfilled';
  9. this.value = value;
  10. this.callbacks.forEach(cb => cb.onFulfilled(value));
  11. }
  12. };
  13. executor(resolve);
  14. }
  15. then(onFulfilled) {
  16. return new MyPromise((resolve) => {
  17. if (this.state === 'fulfilled') {
  18. const result = onFulfilled(this.value);
  19. resolve(result);
  20. } else {
  21. this.callbacks.push({ onFulfilled });
  22. }
  23. });
  24. }
  25. }

2. 实现Promise.all

题目:实现Promise.all,接收一个Promise数组,返回所有Promise完成后的结果数组。
解析
需处理成功和失败两种情况,失败时直接拒绝。
代码实现

  1. function myPromiseAll(promises) {
  2. return new Promise((resolve, reject) => {
  3. const results = [];
  4. let completed = 0;
  5. promises.forEach((promise, index) => {
  6. promise.then(
  7. (value) => {
  8. results[index] = value;
  9. completed++;
  10. if (completed === promises.length) resolve(results);
  11. },
  12. (error) => reject(error)
  13. );
  14. });
  15. });
  16. }

五、总结与备考建议

  1. 分模块练习:将手写题按基础语法、函数、对象、异步等分类,逐个击破。
  2. 理解本质:手写题的核心是考察对JS底层机制的理解,而非死记硬背。
  3. 模拟面试环境:在限定时间内完成题目,培养快速解题能力。
  4. 代码复盘:每次练习后对比标准答案,分析差异与优化点。

通过系统练习本文整理的手写JS题,开发者可全面提升对JavaScript核心知识的掌握,在面试中脱颖而出。

相关文章推荐

发表评论