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

news2024/9/22 21:20:58

文章目录

  • 前言
  • 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,直接返回 null

    const type = typeof obj; // 获取 obj 的数据类型

    if (type !== 'object' && type !== 'function') return obj; // 如果 obj 是基本数据类型或函数类型,直接返回 obj

    const 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);

后言

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1264293.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

摄影网站的技术 SEO:提示和最佳实践

摄影就是要给人留下良好的第一印象。如果你想在竞争中领先&#xff0c;摄影师的SEO是您可以采用的最佳营销方法之一。 我们都曾有过这样的经历&#xff1a;你建立了一个漂亮的作品集网站来吸引更多的业务。网站上线并在社交媒体上推广后&#xff0c;您就可以坐等了。网站访问量…

线程池在Java中的应用实践

摘要&#xff1a;在实际业务场景中&#xff0c;线程池发挥着重要作用。本文将详细解答在高并发、任务执行时间短、并发不高、任务执行时间长以及并发高、业务执行时间长的业务场景下&#xff0c;如何使用线程池进行优化。 一、高并发、任务执行时间短的业务场景 在高并发、任务…

python服装电商系统vue购物商城django-pycharm毕业设计项目推荐

系统面向的使用群体为商家和消费者&#xff0c;商家和消费者所承担的功能各不相同&#xff0c;所对象的权限也各不相同。对于消费者和商家设计的功能如下&#xff1a; 对于消费者设计了五大功能模块&#xff1a; &#xff08;1&#xff09; 商品信息&#xff1a;用户可在商品…

【黑马甄选离线数仓day06_核销主题域开发】

1. 核销主题_DWD和DWM层 1.0 ODS层 操作数据存储层: Operate Data Store 核心理念: 几乎和源数据保持一致,粒度相同 注意事项: 同步方式(全量同步,全量覆盖,增量仅新增,增量新增和更新) 内部表 分区表(部分) 指定字符分隔符 orc zlib 第二天的时候已经完成了从mysql以及sq…

蓝蜂虚拟网络工具配置说明

虚拟网络工具配置说明 注意&#xff1a; 1、在使用虚拟网络工具前&#xff0c;需保证EG20网关可以连接到EMCP云平台&#xff0c;并且设备已经绑定在对应的账号下&#xff0c;同时固件版本为v1.6.6以上。如果不是&#xff0c;点击固件版本处的更新&#xff0c;如下图所示。 2…

GitHub----使用记录

一、上传文件到仓库 1、首先新建一个github仓库 然后先记住这一句指令 2、下载git工具 https://git-scm.com/downloads 下载工具安装不用运行 3、使用git工具上传文件并推送 找到你想上传的文件的位置&#xff0c;右击git Bush here git init &#xff1a;初始化这个仓…

【Python 训练营】N_11 模拟进度条

题目 格式化输出进度条&#xff0c;具体格式如下&#xff1a; 分析 需要格式化打印&#xff0c;进度条随时间显示进展&#xff0c;需要用time模块的sleep()函数。 答案 import time # 导入time模块 length 100 # 定义进度长度模块 for i in range(1,length1): # 遍历1&…

Corel产品注册机Corel Products KeyGen 2023 – XFORCE解决会声会影2023试用30天

CorelDRAW注册机2023支持全系列产品_Corel Products KeyGen 2023 X-FORCE v8 CorelDRAW注册机2023支持全系列产品_Corel Products KeyGen 2023 X-FORCE v8&#xff0c;Corel产品注册机&#xff08;Corel Products KeyGen 2023 – XFORCE&#xff09;&#xff0c;支持Corel旗下所…

TDL CDL信道模型

文章目录 一 TDL二 CDL三 CDL TDL区别 TDL&#xff1a;(Tapped Delay Line&#xff0c;抽头延迟线) CDL&#xff1a;(Clustered Delay Line&#xff0c;集群延迟线) 一 TDL 定义&#xff1a;由一组不同衰落系数和不同时延的抽头组成。全频率范围为&#xff1a;0.5GHz~100GHz&am…

【刷题笔记】分糖果||数组||暴力通过||符合思维方式||多案例分析

分发糖果 文章目录 分发糖果1 题目描述2 题目分析2.1 寻找波峰波谷2.2 从波底往波峰攀爬&#xff01;2.2 计算糖果 3 代码附录1 1 题目描述 https://leetcode.cn/problems/candy/ n 个孩子站成一排。给你一个整数数组 ratings 表示每个孩子的评分。 你需要按照以下要求&…

怎么判断香港服务器的性能好不好?

随着互联网的不断发展&#xff0c;越来越多的人开始使用香港服务器来搭建自己的网站或者应用。但是&#xff0c;对于初次使用香港服务器的用户来说&#xff0c;往往会遇到一个问题&#xff1a;怎么判断香港服务器的性能好不好? 首先我们需要了解香港服务器的性能主要取决于哪些…

智能优化算法应用:基于蝙蝠算法无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于蝙蝠算法无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于蝙蝠算法无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.蝙蝠算法4.实验参数设定5.算法结果6.参考文献7.MATLAB…

iconfont 使用彩色图标

1、下载iconfont到本地 2、全局安装 iconfont-tools npm install -g iconfont-tools 3、在iconfont解压目录下执行命令、一直回车 iconfont-tools 4、文件拷贝 执行完上述命令后会生成iconfont-weapp目录&#xff0c;将iconfont-weapp目录下的iconfont-weapp- icon.css文件…

二叉树之推排序(升序)

目录 1.思路1.1大堆的建立方法1.2排序的方法 2.代码实现以及测试代码 1.思路 如何将一个堆进行排序&#xff0c;并变成升序&#xff1f;首先&#xff0c;如果要完成升序&#xff0c;那我们可以建立一个大堆&#xff0c;因为大堆可以选出一个最大的值放在堆的最上面&#xff0c…

舞蹈店管理系统服务预约会员小程序效果如何

舞蹈的作用很广&#xff0c;也有大量求学者&#xff0c;每个城市也有大小各异的舞蹈品牌店&#xff0c;他们承接商演、也会教学员、宣传拓展生意等&#xff0c;因此近些年来&#xff0c;随着互联网深入及短视频&#xff0c;舞蹈业市场规模也在增加。 而在门店经营中&#xff0…

Go 编程语言详解:用途、特性、与 Python 和 C++ 的比较

什么是Go? Go是一个跨平台、开源的编程语言Go可用于创建高性能应用程序Go是一种快速、静态类型、编译型语言&#xff0c;感觉上像动态类型、解释型语言Go由Robert Griesemer、Rob Pike和Ken Thompson于2007年在Google开发Go的语法类似于C Go用于什么&#xff1f; Web开发&…

QT中的 容器(container)-大全

一、介绍 Qt库提供了一套通用的基于模板的容器类&#xff0c;可以用这些类存储指定类型的项。比如&#xff0c;你需要一个大小可变的QString的数组&#xff0c;则使用QVector<QString>。 这些容器类比STL&#xff08;C标准模板库&#xff09;容器设计得更轻量、更安全并…

快速了解Spring AOP的概念及使用

文章目录 1. AOP概念1.1 什么是AOP&#xff1f;1.2 什么是Spring AOP&#xff1f; 2. Spring AOP的使用2.1 引入Spring AOP依赖2.2 编写AOP程序 3. Spring AOP详解3.1 Spring AOP核心概念1. 切点&#xff08;Pointcut&#xff09;2. 连接点&#xff08;Join Point&#xff09;3…

Linux系统编程 day06 进程间通信

进程间通信 1. 进程间通信的概念2. 匿名管道pipe3. 命名管道FIFO4. 内存映射区 1. 进程间通信的概念 在Linux的环境下&#xff0c;进程地址空间是相互独立的&#xff0c;每个进程有着各自不同的用户地址空间。一个进程不能访问另一个进程中的内容&#xff0c;要进行数据交换必…

[MySQL--基础]函数、约束

hello! 这里是欧_aita的频道。 今日语录:不管你觉得自己能做什么&#xff0c;或者你觉得你不能做什么&#xff0c;你都是对的。 祝福语&#xff1a;愿你的程序像太阳一样明亮&#xff0c;给世界带来温暖和光明。 大家可以在评论区畅所欲言&#xff0c;可以指出我的错误&#xf…