前端开发中,手写题可以帮助我们巩固基础知识,提升编程能力。以下是10个常考的前端手写题及其相应的代码示例和解析。

1. 实现一个深拷贝函数

深拷贝是指创建一个新对象,该对象的属性是原对象属性值的副本。下面是一个深拷贝的简单实现。

function deepClone(obj) {
    if (obj === null || typeof obj !== 'object') {
        return obj; // 如果是基本类型,直接返回
    }

    const clone = Array.isArray(obj) ? [] : {};

    for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
            clone[key] = deepClone(obj[key]); // 递归拷贝
        }
    }

    return clone;
}

2. 实现一个防抖函数

防抖主要用于控制函数的触发频率,常见于输入框搜索等场景。

function debounce(func, delay) {
    let timer;
    return function(...args) {
        if (timer) clearTimeout(timer);
        timer = setTimeout(() => {
            func.apply(this, args);
        }, delay);
    };
}

3. 实现一个节流函数

节流常用于限制高频率事件的执行,如滚动事件。

function throttle(func, limit) {
    let lastFunc;
    let lastRan;
    return function(...args) {
        if (!lastRan) {
            func.apply(this, args);
            lastRan = Date.now();
        } else {
            clearTimeout(lastFunc);
            lastFunc = setTimeout(() => {
                if (Date.now() - lastRan >= limit) {
                    func.apply(this, args);
                    lastRan = Date.now();
                }
            }, limit - (Date.now() - lastRan));
        }
    };
}

4. 实现一个简单的事件总线

事件总线可以帮助实现不同模块之间的解耦。

class EventBus {
    constructor() {
        this.events = {};
    }

    on(event, listener) {
        if (!this.events[event]) {
            this.events[event] = [];
        }
        this.events[event].push(listener);
    }

    emit(event, ...args) {
        if (this.events[event]) {
            this.events[event].forEach(listener => listener(...args));
        }
    }

    off(event, listener) {
        if (!this.events[event]) return;
        this.events[event] = this.events[event].filter(l => l !== listener);
    }
}

5. 实现 Promise.all

Promise.all 接受一个 promise 数组,只有当所有的 promise 都成功,才会返回成功的结果。

function promiseAll(promises) {
    return new Promise((resolve, reject) => {
        const result = [];
        let completed = 0;

        promises.forEach((promise, index) => {
            Promise.resolve(promise)
                .then(value => {
                    result[index] = value;
                    completed += 1;
                    if (completed === promises.length) {
                        resolve(result);
                    }
                })
                .catch(reject);
        });
    });
}

6. 实现一个简单的继承

实现一个简单的原型继承。

function inheritPrototype(child, parent) {
    child.prototype = Object.create(parent.prototype);
    child.prototype.constructor = child;
}

7. 实现一个字符串反转函数

字符串反转是一个常见的算法问题。

function reverseString(str) {
    return str.split('').reverse().join('');
}

8. 实现一个数组去重

对数组进行去重,常用方法有 ES6 Set。

function uniqueArray(arr) {
    return Array.from(new Set(arr));
}

// 另一种手写去重方法
function uniqueArrayManual(arr) {
    return arr.filter((item, index) => arr.indexOf(item) === index);
}

9. 实现数组扁平化

将多维数组展开成一维数组。

function flattenArray(arr) {
    return arr.reduce((flat, item) => 
        flat.concat(Array.isArray(item) ? flattenArray(item) : item), []);
}

10. 实现一个斐波那契数列

斐波那契数列是常见的数学题,递归或循环均可实现。

function fibonacci(n) {
    if (n <= 1) return n;
    return fibonacci(n - 1) + fibonacci(n - 2);
}

// 使用循环
function fibonacciIterative(n) {
    let a = 0, b = 1, temp;
    for (let i = 2; i <= n; i++) {
        temp = a + b;
        a = b;
        b = temp;
    }
    return b;
}

以上是10个常见的前端手写题以及解决方案,通过这些题目,可以提升你的编程能力和面试技巧。通过不断练习,你将能够更加自信地应对面试中的各种问题。

点赞(0) 打赏

微信小程序

微信扫一扫体验

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部