欢迎来到3672js教程,我们关注js教程、js框架、js代码特效等。

10个JavaScript面试常考的前端手写题总结,

3672Js.Com2024-03-23 02:24 来源:未知 阅读:15773 关注度2

10个JavaScript面试常考的前端手写题总结,


目录
  • 1. 实现一个简单的 JavaScript 函数,用于判断一个对象是否为空
  • 2. 手写数组去重
  • 3. 实现bind函数
  • 4. 实现数组的map方法
  • 5. 实现简易版的深拷贝
  • 6. 实现防抖函数(debounce)
  • 7. 实现节流函数(throttle)
  • 8. 实现 Promise 的 then 方法
  • 9. 实现简易版 Ajax 请求
  • 10. 实现一个简易版的事件委托

1. 实现一个简单的 JavaScript 函数,用于判断一个对象是否为空

判断对象是否为空的函数 这个函数通过遍历对象的所有属性来检查是否有任何实际定义的键。如果在循环中找到了一个键,则立即返回false,表示对象不为空。如果没有找到任何键,则在循环结束后返回true,表示对象为空。

function isEmptyObject(obj) {
    for (var key in obj) {
        if (obj.hasOwnProperty(key)) {
            return false;
        }
    }
    return true;
}

2. 手写数组去重

数组去重 第一个实现是使用传统的方法,创建一个新的数组,并利用indexOf方法检查当前元素是否已存在于新数组中,不存在则添加进去。 第二个实现利用了ES6中的Set数据结构,它不允许重复值,所以可以直接将数组转换为Set再转回数组达到去重效果。

function unique(arr) {
    let res = [];
    for(let i = 0; i < arr.length; i++) {
        if(res.indexOf(arr[i]) === -1) {
            res.push(arr[i]);
        }
    }
    return res;
}
// 或者使用ES6的新特性Set
function uniqueES6(arr) {
    return [...new Set(arr)];
}

3. 实现bind函数

实现bind函数 JavaScript中原生的bind函数可以创建一个新的函数,在调用时设置其this上下文并传递预设参数。这里的实现同样创建了一个新的函数,并在其内部调用了原函数,同时保证了this指向和传参的正确性。

Function.prototype.myBind = function(context, ...args) {
    const self = this;
    return function(...newArgs) {
        return self.apply(context, [...args, ...newArgs]);
    };
};

4. 实现数组的map方法

实现map方法 Array.prototype.map() 方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。这里我们模拟了这个行为,对原数组进行遍历,并将回调函数应用于每个元素,然后将结果推入新数组。

Array.prototype.myMap = function(callback, thisArg) {
    const newArray = [];
    for (let i = 0; i < this.length; i++) {
        newArray.push(callback.call(thisArg, this[i], i, this));
    }
    return newArray;
};

5. 实现简易版的深拷贝

简易版深拷贝 实现了一个递归函数,用于复制给定对象的所有属性和嵌套对象。当遇到非对象或null类型的值时直接返回,否则创建一个新的对象并递归地复制原对象的所有属性。

function deepClone(obj) {
    if (typeof obj !== 'object' || obj === null) {
        return obj;
    }
    let cloneObj = Array.isArray(obj) ? [] : {};
    for(let key in obj) {
        if (obj.hasOwnProperty(key)) {
            cloneObj[key] = deepClone(obj[key]);
        }
    }
    return cloneObj;
}

6. 实现防抖函数(debounce)

防抖函数(debounce) 防抖函数用于限制某个函数在一定时间内只能执行一次。例如在窗口 resize 或输入框连续输入事件中,防止短时间内多次触发。这里的实现是在每次调用时清除上一次的延时任务,然后重新设置一个延时任务,只有在指定时间间隔内没有再次调用时,才会执行原函数。

function debounce(func, wait) {
    let timeout;
    return function(...args) {
        clearTimeout(timeout);
        timeout = setTimeout(() => {
            func.apply(this, args);
        }, wait);
    };
}

7. 实现节流函数(throttle)

节流函数(throttle) 节流函数确保在一定时间内,只允许函数执行一次。与防抖不同的是,节流保证了在持续触发的情况下,至少每隔一定时间会执行一次函数。这里的实现是在触发函数时记录上一次执行的时间,如果当前时间与上次执行时间差大于设定的时间间隔,则执行函数

function throttle(func, delay) {
    let prev = Date.now();
    return function(...args) {
        const now = Date.now();
        if (now - prev >= delay) {
            func.apply(this, args);
            prev = now;
        }
    };
}

8. 实现 Promise 的 then 方法

实现Promise的then方法 Promise的then方法接受两个回调函数作为参数,分别处理成功和失败的情况。这里模拟Promise的状态机,根据Promise当前状态异步执行相应的回调函数,并处理回调返回的新Promise。

MyPromise.prototype.then = function(onFulfilled, onRejected) {
    let self = this;
    return new MyPromise((resolve, reject) => {
        if (self.status === 'fulfilled') {
            setTimeout(() => { // 异步执行
                try {
                    let x = onFulfilled(self.value);
                    resolvePromise(x, resolve, reject);
                } catch(e) {
                    reject(e);
                }
            }, 0);
        } else if (self.status === 'rejected') {
            setTimeout(() => {
                try {
                    let x = onRejected(self.reason);
                    resolvePromise(x, resolve, reject);
                } catch(e) {
                    reject(e);
                }
            }, 0);
        } else {
            self.onResolvedCallbacks.push(() => {
                setTimeout(() => {
                    try {
                        let x = onFulfilled(self.value);
                        resolvePromise(x, resolve, reject);
                    } catch(e) {
                        reject(e);
                    }
                }, 0);
            });
            self.onRejectedCallbacks.push(() => {
                setTimeout(() => {
                    try {
                        let x = onRejected(self.reason);
                        resolvePromise(x, resolve, reject);
                    } catch(e) {
                        reject(e);
                    }
                }, 0);
            });
        }
    });
};

​​​​​​​function resolvePromise(value, resolve, reject) {
    if (value instanceof MyPromise) {
        value.then(resolve, reject);
    } else {
        resolve(value);
    }
}

9. 实现简易版 Ajax 请求

简易版Ajax请求 实现了一个基于XMLHttpRequest的简易Ajax请求函数,返回一个Promise对象。当请求完成且状态码正常时解析响应内容并resolve,否则reject。

function ajax(url, method, data) {
    return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest();
        xhr.open(method, url, true);
        xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
        xhr.onreadystatechange = function() {
            if (xhr.readyState === 4) {
                if (xhr.status >= 200 && xhr.status < 300) {
                    resolve(JSON.parse(xhr.responseText));
                } else {
                    reject(xhr.statusText);
                }
            }
        };
        xhr.onerror = function() {
            reject(xhr.statusText);
        };
        xhr.send(JSON.stringify(data));
    });
}

10. 实现一个简易版的事件委托

实现事件委托 事件委托是一种优化事件处理的方式,通过监听父级元素的事件,然后通过事件对象判断触发事件的具体子元素,从而减少绑定事件的数量。在这个实现中,当父元素接收到事件时,会向上遍历事件传播链,查找是否匹配特定选择器的目标元素,如果匹配就执行处理器函数。

function delegateEvent(element, selector, eventType, handler) {
    element.addEventListener(eventType, function(event) {
        let target = event.target;
        while (target && target !== this) {
            if (target.matches(selector)) {
                handler.call(target, event);
                break;
            }
            target = target.parentNode;
        }
    });
}

到此这篇关于10个JavaScript面试常考的前端手写题总结的文章就介绍到这了,更多相关JavaScript常考手写题内容请搜索3672js教程以前的文章或继续浏览下面的相关文章希望大家以后多多支持3672js教程!

您可能感兴趣的文章:
  • JavaScript常考手写题之柯里化与数组扁平化的实现
  • JS面试之手写节流防抖详解
  • JS面试必备之手写instanceof,深拷贝,节流和防抖
  • JS面试必备之手写call/apply/bind/new
  • JavaScript面试必备技巧之手写一个Promise
  • JavaScript常见手写题超全汇总

本站文章为3672js教程网友分享投稿,版权归原作者,欢迎任何形式的转载,但请务必注明出处。同时文章内容如有侵犯了您的权益,请联系我们处理。
评论已被关闭