js手写面试题【附带注释】

文章目录

  • 前言
  • 数组方法手写
    • push
    • pop
    • shift
    • unshift
    • cancat
    • slice
    • splice
    • forEach
    • map
    • reduce
    • find
  • 手写订阅发布
  • 手写单例模式
  • 后言

前言

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


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

数组方法手写

push

Array.prototype.myPush = function(...elements) {// 获取当前数组的长度const currentLength = this.length;// 遍历要添加的元素,并逐个添加到数组末尾elements.forEach((element) => {this[currentLength] = element;currentLength++;});// 返回新数组的长度return this.length;
};// 使用示例
const arr = [1, 2, 3];
arr.myPush(4, 5);
console.log(arr); // [1, 2, 3, 4, 5]

pop

// 定义一个pop函数
function myPop(arr) {// 如果数组为空,直接返回undefinedif (arr.length === 0) {return undefined;}// 获取数组最后一个元素const poppedItem = arr[arr.length - 1];// 删除数组最后一个元素arr.length = arr.length - 1;// 返回被删除的元素return poppedItem;
}// 示例用法
const myArray = [1, 2, 3, 4, 5];
const poppedItem = myPop(myArray);
console.log(poppedItem); // 输出 5
console.log(myArray); // 输出 [1, 2, 3, 4]

shift

// 定义一个shift函数
function myShift(arr) {// 如果数组为空,直接返回undefinedif (arr.length === 0) {return undefined;}// 获取数组第一个元素const shiftedItem = arr[0];// 移除数组第一个元素for (let i = 0; i < arr.length - 1; i++) {arr[i] = arr[i + 1];}arr.length = arr.length - 1;// 返回被删除的元素return shiftedItem;
}// 示例用法
const myArray = [1, 2, 3, 4, 5];
const shiftedItem = myShift(myArray);
console.log(shiftedItem); // 输出 1
console.log(myArray); // 输出 [2, 3, 4, 5]

unshift

// 定义一个unshift函数
function myUnshift(arr, ...items) {// 获取items的长度const len = items.length;// 将数组中的元素向后移动,为新的元素腾出位置for (let i = arr.length - 1; i >= 0; i--) {arr[i + len] = arr[i];}// 将新元素插入到数组的开头for (let i = 0; i < len; i++) {arr[i] = items[i];}// 返回新的数组长度return arr.length;
}// 示例用法
const myArray = [1, 2, 3, 4, 5];
const newLength = myUnshift(myArray, 0, -1);
console.log(newLength); // 输出 7
console.log(myArray); // 输出 [0, -1, 1, 2, 3, 4, 5]

cancat

function myConcat(arr, ...args) {// 创建一个新数组,初始值为原数组的所有元素const newArr = arr.slice();// 遍历参数数组for (let i = 0; i < args.length; i++) {// 如果参数是数组,将数组中的每个元素添加到新数组中if (Array.isArray(args[i])) {for (let j = 0; j < args[i].length; j++) {newArr.push(args[i][j]);}} else {// 如果参数不是数组,直接添加到新数组中newArr.push(args[i]);}}// 返回新数组return newArr;
}// 示例用法
const arr1 = [1, 2];
const arr2 = [3, 4];
const newArr = myConcat(arr1, arr2, 5, [6, 7]);
console.log(newArr); // 输出 [1, 2, 3, 4, 5, 6, 7]

slice

function mySlice(arr, start = 0, end = arr.length) {// 创建一个新数组const newArr = [];// 处理负数的情况if (start < 0) {start = arr.length + start;}if (end < 0) {end = arr.length + end;}// 处理 start 和 end 超出数组范围的情况start = Math.max(0, start);end = Math.min(arr.length, end);// 循环从原数组中取出指定范围的元素并添加到新数组中for (let i = start; i < end; i++) {newArr.push(arr[i]);}// 返回新数组return newArr;
}// 示例用法
const arr = [1, 2, 3, 4, 5];
const slicedArr = mySlice(arr, 1, 4);
console.log(slicedArr); // 输出 [2, 3, 4]

splice

function mySplice(arr, index, count, ...elements) {// 处理负数的情况if (index < 0) {index = arr.length + index;}// 计算需要删除的元素的个数const numToDelete = Math.min(count, arr.length - index);// 创建一个新数组,初始值为原数组中需要删除的元素const deletedElements = [];for (let i = 0; i < numToDelete; i++) {deletedElements.push(arr[index + i]);}// 从原数组中删除需要删除的元素for (let i = index + numToDelete - 1; i >= index; i--) {arr.splice(i, 1);}// 将新元素添加到原数组中指定的位置for (let i = 0; i < elements.length; i++) {arr.splice(index + i, 0, elements[i]);}// 返回被删除的元素组成的新数组return deletedElements;
}// 示例用法
const arr = [1, 2, 3, 4, 5];
const deletedElements = mySplice(arr, 1, 2, 6, 7);
console.log(arr); // 输出 [1, 6, 7, 4, 5]
console.log(deletedElements); // 输出 [2, 3]

forEach

function myForEach(arr, callback) {for (let i = 0; i < arr.length; i++) {// 调用回调函数,传入当前元素、当前索引和原数组callback(arr[i], i, arr);}
}// 示例用法
const arr = [1, 2, 3];
myForEach(arr, (item, index, array) => {console.log(item); // 输出每个元素console.log(index); // 输出每个元素的索引console.log(array); // 输出原数组
});

map

function myMap(arr, callback) {const result = [];for (let i = 0; i < arr.length; i++) {// 调用回调函数,传入当前元素、当前索引和原数组const newItem = callback(arr[i], i, arr);// 将回调函数的返回值添加到新数组中result.push(newItem);}return result;
}// 示例用法
const arr = [1, 2, 3];
const doubled = myMap(arr, (item, index, array) => {return item * 2;
});
console.log(doubled); // 输出 [2, 4, 6]

reduce

function myReduce(arr, callback, initialValue) {let accumulator = initialValue === undefined ? arr[0] : initialValue;for (let i = initialValue ? 0 : 1; i < arr.length; i++) {// 调用回调函数,传入累加器、当前元素、当前索引和原数组accumulator = callback(accumulator, arr[i], i, arr);}return accumulator;
}// 示例用法
const arr = [1, 2, 3, 4, 5];
const sum = myReduce(arr, (accumulator, item, index, array) => {return accumulator + item;
});
console.log(sum); // 输出 15

find

function myFind(arr, callback) {for (let i = 0; i < arr.length; i++) {if (callback(arr[i], i, arr)) {return arr[i];}}return undefined;
}// 示例用法
const arr = [1, 2, 3, 4, 5];
const result = myFind(arr, (item) => {return item > 3;
});
console.log(result); // 输出 4

手写订阅发布

class Subject {constructor() {this.observe = [];}// 添加观察者addObserver(observer){this.observe.push(observer)}// 删除观察者removeObserver(observer){this.observe = this.observe.filter(obs => obs !== observer)}// 状态变化notfiy(data){this.observe.forEach(observer=>{observer.update(data)})}
}class Observer {update(data){console.log(`数据:${data}`)}
}const subject = new Subject()const objectone = new Observer()
const objecttwo = new Observer()subject.addObserver(objectone)
subject.addObserver(objecttwo)subject.removeObserver(objecttwo)subject.notfiy("hello word lpz")

手写单例模式

var Singleton = (function() {// 实例变量,用于存储单例实例var instance;// 单例对象的构造函数function Singleton() {// 在这里可以初始化单例对象this.name = "Singleton Instance";}// 获取单例实例的方法Singleton.getInstance = function() {// 如果实例不存在,则创建新实例并赋值给 instanceif (!instance) {instance = new Singleton();}// 返回单例实例return instance;};// 返回构造函数,使其可以像类一样使用,但无法通过 new Singleton() 实例化return Singleton;
})();// 测试单例模式
var instance1 = Singleton.getInstance();
var instance2 = Singleton.getInstance();// 由于是单例模式,instance1 和 instance2 应该是相同的实例
console.log(instance1 === instance2); // 输出 true

后言

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

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

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

相关文章

代码安全-exe的代码签名和代码混淆加密

信息安全相关 - 建设篇 第四章 代码安全-exe的代码签名和代码混淆加密 信息安全相关 - 建设篇系列文章回顾代码安全-exe的代码签名和代码混淆加密前言实施步骤C#程序的程序集引用使用强命名(可选)Windows Server AD CA 制作自定义的证书模板,用于代码签名生成拥有自签名CA的代…

Java并发编程CAS

目录 CAS是什么 CAS存在问题 ABA问题 CPU开销大 不能保证代码块的原子性 CAS实例 CAS是什么 CAS(Compare and Swap,比较并交换)是一种并发编程中的原子操作,用于实现多线程环境下的无锁同步。它是一种乐观锁策略,通过比较内存中的值与期望值是否相等来决定是否更…

机柜浪涌保护器行业应用解决方案

机柜浪涌保护器是一种用于保护机柜内电子设备免受雷电或其他瞬时过电压影响的装置&#xff0c;它可以有效地限制或引导电涌电流&#xff0c;避免设备损坏或数据丢失。机柜浪涌保护器广泛应用于通信、电力、工业控制、医疗、安防等领域&#xff0c;是保障机柜系统安全稳定运行的…

龟兔赛跑python小游戏

# turtle控制游戏角色&#xff0c;Screen控制画布 from turtle import Turtle,Screen import time# 创建画布 screen Screen()# 改变画布大小 screen.setup(1200,600)# 设置背景图&#xff08;必须是gif格式&#xff09; screen.bgpic(背景图.gif)# 设置乌龟的角色 screen.reg…

centos服务器扩容

centos服务器扩容 我的情况是&#xff0c;原服务器是一个80g磁盘&#xff0c;管理员又追加了120G到这块磁盘上&#xff0c;需要把这120G重新追加使用。 请确认你遇到的情况是否和我初始截图一致&#xff0c;再往下看&#xff0c;免得浪费时间与精力 服务器中有120G尚未使用&…

JavaEE(SpringMVC)期末复习(选择+填空+解答)

文章目录 JavaEE期末复习一、单选题&#xff1a;二、多选题三、填空题四、解答 JavaEE期末复习 一、单选题&#xff1a; 1.Spring的核⼼技术是&#xff08; A &#xff09;&#xff1f; A依赖注入 B.JdbcTmplate C.声明式事务 D.资源访问 Spring的核心技术包括依赖注入&#x…

NOI / 1.8编程基础之多维数组 提问24:蛇形填充数组 c语言

描述 用数字1,2,3,4,...,n*n这n2个数蛇形填充规模为n*n的方阵。 蛇形填充方法为&#xff1a; 对于每一条左下-右上的斜线&#xff0c;从左上到右下依次编号1,2,...,2n-1&#xff1b;按编号从小到大的顺序&#xff0c;将数字从小到大填入各条斜线&#xff0c;其中编号为奇数的…

[Android] c++ 通过 JNI 调用 JAVA

Calling Java from C with JNI - CodeProject

Python进程之间同步实现代码

1、 # coding : UTF-8 import multiprocessing, time # 导入多进程的开发模块 def worker(dict): # 进程的处理函数 while True: # 持续售票 number dict.get("ticket") # 获得当前的票数 if number > 0 : # 如果现在还有剩余票 …

运维 | 四层和七层负载均衡介绍

关注: CodingTechWork 负载均衡 负载均衡介绍 概念 负载均衡是建立在现有的网络结构之上&#xff0c;提供一种廉价且透明的方式进行网络设备和服务器带宽的扩展&#xff0c;从而增加吞吐量&#xff0c;加强应用服务的数据处理能力&#xff0c;有效提高网络的灵活性和可用性。…

深度视觉目标跟踪进展综述

1 引言 目标跟踪旨在基于初始帧中指定的感兴趣目标( 一般用矩形框表示) &#xff0c;在后续帧中对该目标进行持续的定位。 基于深度学习的跟踪算法&#xff0c;采用的框架包括相关滤波器、分类式网络、双路网络等。 处理跟踪任务的角度&#xff0c;分为基于匹配思路的双路网…

操作系统——操作系统概论s

一、操作系统基本概念 1 操作系统定义 操作系统是裸机上的第一层软件&#xff0c;它是对硬件系统功能的首次扩充&#xff0c; 用以填补人与机器之间的鸿沟。 OS定义&#xff1a;操作系统是控制和管理计算机系统内各种硬件和软件资源&#xff0c;有效地组织多道程序运行的系统软…

makefile中常见的环境变量

makefile中常见的环境变量 1&#xff09;CFLAGS&#xff1a;用于指定C语言编译器的选项&#xff0c;例如优化级别、警告级别、编译器标志等。 2&#xff09;CXXFLAGS&#xff1a;用于指定C语言编译器的选项&#xff0c;与CFLAGS类似&#xff0c;但专门针对C代码。 3&#xff0…

W2311283-可燃气体监测仪怎么监测燃气管道

可燃气体监测仪怎么有效监测燃气管道 燃气管道遍布于城市地下各处&#xff0c;作为城市生命线的一部分&#xff0c;一旦燃气管网出现泄露问题便是牵一发而动全身&#xff0c;城市的整体安全也会受到威胁。但是如何才能科学管理和监测燃气管网呢&#xff1f; 燃气管网监测系统便…

米贸搜|如何设置 Facebook 转换 API + 事件重复数据删除

Facebook Pixel 可让您跟踪用户在您网站上的行为、收集再营销受众并创建相似对象。如果 Facebook 像素实现正确&#xff0c;它将向 FB 机器学习算法提供相关信息。 FB ML 将使用像素数据向最有可能转化的人展示您的广告。 几年来&#xff0c;我们可以通过 JavaScript 代码、应…

MapReduce概念

1、概念 MapReduce 是一种编程模型&#xff0c;用于大规模数据集的并行处理。它是由 Google 开发的&#xff0c;用于处理大规模数据集的分布式计算框架。 MapReduce 的主要作用是将一个大的任务分解成多个小的任务&#xff0c;并在多台机器上并行执行这些任务。它包括两…

「我在淘天做技术」迈步从头越 - 阿里妈妈广告智能决策技术的演进之路

作者&#xff1a;妙临、霁光、玺羽 一、前言 在线广告对于大多数同学来说是一个既熟悉又陌生的技术领域。「搜广推」、「搜推广」等各种组合耳熟能详&#xff0c;但广告和搜索推荐有本质区别&#xff1a;广告解决的是“媒体-广告平台-广告主”等多方优化问题&#xff0c;其中媒…

localForage存储

一、什么是 localForage 当我们的存储量比较大的时候&#xff0c;我们一定会想到我们的 indexedDB&#xff0c;让我们在浏览器中也可以 使用数据库这种形式来玩转本地化存储&#xff0c;然而 indexedDB 的使用是比较繁琐而复杂的&#xff0c; 有一定的学习成本&#xff0c;但 …

STM32串口波特率在使用中的改变方法

上次讲到了STM32串口波特率在使用中的改变&#xff1a; void MX_USART_UART_Init(UART_HandleTypeDef *huart, USART_TypeDef * uart, int BaudRate) {huart->Instance uart;huart->Init.BaudRate BaudRate;huart->Init.WordLength UART_WORDLENGTH_8B;huart->…

力扣二叉树--第三十三天

前言 前面都是遍历&#xff0c;今天是构造二叉树。 前序和中序可以唯一确定一棵二叉树。 后序和中序可以唯一确定一棵二叉树。 前序和后序不能唯一确定一棵二叉树&#xff01; 内容 一、从中序与后序遍历序列构造二叉树 106. 从中序与后序遍历序列构造二叉树 给定两个整…