某东大厂面试js手写题【手写代码附带注释,放心食用,博主亲测】

本文主要是介绍某东大厂面试js手写题【手写代码附带注释,放心食用,博主亲测】,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 前言
  • js实现push方法
  • js实现订阅发布
  • 手写防抖节流
  • 手写reduce方法
  • 深拷贝
  • es5去重
  • 数组多维数组去重排序
  • 简单递归实现树形结构输出遍历
  • 后言

前言

hello world欢迎来到前端的新世界


😜当前文章系列专栏:前端面试
🐱‍👓博主在前端领域还有很多知识和技术需要掌握,正在不断努力填补技术短板。(如果出现错误,感谢大家指出)🌹
💖感谢大家支持!您的观看就是作者创作的动力

js实现push方法

let Arr = [1, 2, 3];Array.prototype.push = function (...items) {  // 通过Array.prototype.push的这个属性我们定义的方法顶替const len = this.length;  // 当前数组的长度const itemCount = items.length;  // 值的长度for (let i = 0; i < itemCount; i++) {  // 把每一个值都进行循环this[len + i] = items[i];  // 把当前数组长度+i,i是循环的我们要添加的itemCount的长度的循环,第一个是1到我们数组的最长的长度根据我们的数组的特性,根据没有的索引进行添加值来操作,然后从而实现push添加}this.length = len + itemCount;  // 更新数组长度return this.length;  // 返回数组更新长度
}Arr.push(99)  // 调用方法
console.log(Arr)  // 查看数组调用后的后果
  • 这里的this代表的当前的数组也就是下图中的这里,arr这里。
  • 然后通过重新获取我们数组的长度(因为我们在循环添加数组的新属性的时候,我们的数组添加的过程中是用的 this[len + i] = items[i] 这种形式; JavaScript 中的数组是一种特殊的对象,可以动态地添加属性(也就是索引)。当你使用一个不存在的索引访问或修改数组时,JavaScript 会自动将它作为一个新的属性添加到数组对象上,并为其赋予相应的值。
  • 然后就是值 我们传入值的长度
  • 然后就是循环 这里大家应该懂吧,就是用let 声明一个i 然后循环条件就是i<传入值的长度的时候,我们的i++
  • 循环的内容使用this[当前数组长度 + i] = 传入的值[i]
  • 然后循环完后,是通过this.length 来确定我们当前数组的长度,当前数组长度 + 我们传入的数组的长度,就是我们当前数组长度
  • 然后 返回最终我们的数组长度
    在这里插入图片描述

js实现订阅发布

// 
// 定义一个主题类 Subject
class Subject {constructor() {this.observers = []; // 初始化观察者数组}// 添加观察者addObserver(observer){this.observers.push(observer); // 将新的观察者添加到观察者数组中}// 删除观察者removeObserver(observer){this.observers = this.observers.filter(obs => obs !== observer); // 通过过滤将特定的观察者从数组中移除}// 状态变化通知观察者notify(data){this.observers.forEach(observer => {observer.update(data); // 遍历观察者数组,调用每个观察者的 update 方法});}
}// 定义一个观察者类 Observer
class Observer {update(data){console.log(`数据:${data}`); // 当接收到主题状态变化通知时,执行 update 方法来处理数据}
}const subject = new Subject(); // 创建一个主题实例const observerOne = new Observer(); // 创建第一个观察者实例
const observerTwo = new Observer(); // 创建第二个观察者实例subject.addObserver(observerOne); // 将第一个观察者添加到主题的观察者数组中
subject.addObserver(observerTwo); // 将第二个观察者添加到主题的观察者数组中subject.removeObserver(observerTwo); // 从主题的观察者数组中移除第二个观察者subject.notify("hello word lpz"); // 主题状态发生变化,通知所有的观察者进行更新处理

手写防抖节流

// 节流函数
function throttle(fn, delay) {let timer = null; // 设置一个初始值为 null 的定时器变量let lastTime = 0; // 这里的 lastTime 变量用于记录上一次执行函数的时间戳return function(...args) { // 返回一个新的函数const now = performance.now(); // 获取当前时间戳const remainingTime = delay - (now - lastTime); // 计算距离上次执行函数剩余的时间if (remainingTime <= 0) { // 如果剩余时间小于等于 0,则立即执行函数if (timer) { // 如果存在已经设置的定时器,则清除它clearTimeout(timer);timer = null;}fn(...args); // 执行函数lastTime = now; // 更新上一次执行函数的时间戳} else if (!timer) { // 如果剩余时间大于 0,且不存在已经设置的定时器,则设置定时器timer = setTimeout(() => { // 延迟剩余时间后执行函数fn(...args);lastTime = performance.now(); // 更新上一次执行函数的时间戳timer = null; // 清空定时器变量}, remainingTime);}};
}function handle() {console.log("触发");
}let fn = throttle(handle, 2000); // 使用节流函数包装 handle 函数fn(); // 第一次执行// 监听滚动事件,在滚动过程中多次触发函数
window.addEventListener("scroll", fn);

手写reduce方法

Array.prototype.reduce = function(callback, initialValue) {// 首先判断数组是否为空,并且判断回调函数是否为函数类型if (this.length === 0 && typeof callback !== 'function') {throw new TypeError('Array is empty and callback is not a function');}let accumulator = initialValue === undefined ? this[0] : initialValue; // 初始化累加器的值for (let i = initialValue === undefined ? 1 : 0; i < this.length; i++) { // 从初始值开始迭代数组accumulator = callback(accumulator, this[i], i, this); // 调用回调函数进行累加器值的更新}return accumulator; // 返回最终累加器的值};// 测试const array = [1, 2, 3, 4, 5];const sum = array.reduce((acc, cur) => acc + cur, 0);console.log(sum); // 输出 15,即 1 + 2 + 3 + 4 + 5 的和

深拷贝

function deepClone(obj) { // 定义一个函数 deepClone,接受一个对象作为参数if (obj === null) return null; // 如果传入的对象为 null,直接返回 nullconst type = typeof obj; // 获取 obj 的数据类型if (type !== 'object' && type !== 'function') return obj; // 如果 obj 是基本数据类型或函数类型,直接返回 objconst clone = Array.isArray(obj) ? [] : {}; // 创建一个新的空对象或数组for (let key in obj) { // 遍历 obj 的属性if (Object.hasOwnProperty.call(obj, key)) { // 判断属性是否属于 obj 对象本身clone[key] = deepClone(obj[key]); // 递归调用 deepClone 函数,将 obj 对应属性的值赋值给 clone 对应的属性}}return clone; // 返回深拷贝后的对象
}var a = [1,2,3];var b = deepClone(a);b.push(5,5)
console.log(a)
// let b =  deepClone(a);

es5去重

// es5 数组去重
function arrfilter(arr:any[]){let res = arr.filter((item,index)=>{console.log(arr.indexOf(item) === index,item,index,arr.indexOf(item))return arr.indexOf(item) === index})return res;
}console.log(arrfilter(["张三","张三","张三","找死","李斯特"]))

数组多维数组去重排序

// 数组多维数组去重排序
function numberArrFilter(arr) {let newArr = new Set(arr); // 去重把数组转换为set对象let setArr = Array.from(newArr) // 再把set对象转换为数组对象return setArr.sort((a, b) => { // 然后返回排序的结果return a - b;})
}// 数组扁平化 通过递归循环
function flattenArray(arr) {return arr.reduce((result, item) => { // 使用 reduce() 方法对数组进行迭代处理if (Array.isArray(item)) { // 如果当前元素是数组result.push(...flattenArray(item)); // 递归调用扁平化函数,将子数组扁平化后的结果展开并添加到结果数组中} else { // 如果当前元素不是数组result.push(item); // 直接将元素添加到结果数组中}return result; // 返回累积的结果数组}, []); // 初始值是一个空数组
}console.log(numberArrFilter(flattenArray([[1, 2, 3], [4, 5, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 6], [1, 2, 3], [1, 2, 3], [1, 2, 3]])))

简单递归实现树形结构输出遍历

// 递归遍历树形结构function getTree(data) {console.log(data.value);if (data.children) {data.children.forEach(item => getTree(item));}
}// 创建一个简单的树结构
const tree = {value: 1,children: [{value: 2,children: [{ value: 4 },{ value: 5 }]},{value: 3,children: [{ value: 6 },{ value: 7 }]}]
};getTree(tree);

后言

创作不易,要是本文章对广大读者有那么一点点帮助 不妨三连支持一下,您的鼓励就是博主创作的动力

这篇关于某东大厂面试js手写题【手写代码附带注释,放心食用,博主亲测】的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/431164

相关文章

JS常用组件收集

收集了一些平时遇到的前端比较优秀的组件,方便以后开发的时候查找!!! 函数工具: Lodash 页面固定: stickUp、jQuery.Pin 轮播: unslider、swiper 开关: switch 复选框: icheck 气泡: grumble 隐藏元素: Headroom

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

活用c4d官方开发文档查询代码

当你问AI助手比如豆包,如何用python禁止掉xpresso标签时候,它会提示到 这时候要用到两个东西。https://developers.maxon.net/论坛搜索和开发文档 比如这里我就在官方找到正确的id描述 然后我就把参数标签换过来

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

秋招最新大模型算法面试,熬夜都要肝完它

💥大家在面试大模型LLM这个板块的时候,不知道面试完会不会复盘、总结,做笔记的习惯,这份大模型算法岗面试八股笔记也帮助不少人拿到过offer ✨对于面试大模型算法工程师会有一定的帮助,都附有完整答案,熬夜也要看完,祝大家一臂之力 这份《大模型算法工程师面试题》已经上传CSDN,还有完整版的大模型 AI 学习资料,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

Node.js学习记录(二)

目录 一、express 1、初识express 2、安装express 3、创建并启动web服务器 4、监听 GET&POST 请求、响应内容给客户端 5、获取URL中携带的查询参数 6、获取URL中动态参数 7、静态资源托管 二、工具nodemon 三、express路由 1、express中路由 2、路由的匹配 3、路由模块化 4、路由模块添加前缀 四、中间件

代码随想录冲冲冲 Day39 动态规划Part7

198. 打家劫舍 dp数组的意义是在第i位的时候偷的最大钱数是多少 如果nums的size为0 总价值当然就是0 如果nums的size为1 总价值是nums[0] 遍历顺序就是从小到大遍历 之后是递推公式 对于dp[i]的最大价值来说有两种可能 1.偷第i个 那么最大价值就是dp[i-2]+nums[i] 2.不偷第i个 那么价值就是dp[i-1] 之后取这两个的最大值就是d

pip-tools:打造可重复、可控的 Python 开发环境,解决依赖关系,让代码更稳定

在 Python 开发中,管理依赖关系是一项繁琐且容易出错的任务。手动更新依赖版本、处理冲突、确保一致性等等,都可能让开发者感到头疼。而 pip-tools 为开发者提供了一套稳定可靠的解决方案。 什么是 pip-tools? pip-tools 是一组命令行工具,旨在简化 Python 依赖关系的管理,确保项目环境的稳定性和可重复性。它主要包含两个核心工具:pip-compile 和 pip