news 2026/5/24 1:29:10

前端实习面试手写题分享

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
前端实习面试手写题分享

在寻找前端实习的过程中,我们会发现,面试除了考察算法题之外,手写题同样也是高频考点。尤其是在准备中大厂前端面试时,手写能力几乎是必不可少的一部分。这篇文章将围绕几道经典高频手写题展开,包括手写深拷贝、实现寄生组合式继承以及数组扁平化,帮助大家从原理到底层实现进行系统理解。

1.手写深拷贝

深拷贝是指创建一个与原对象完全独立的新对象,不仅复制对象第一层的属性,还会递归复制内部嵌套的对象、数组等引用类型。这样修改新对象时,不会影响原对象。它的核心意义在于“彻底断开引用关系”,常用于状态管理、数据备份以及避免对象共享带来的副作用等场景。

手写深拷贝的核心是递归复制对象中的每一层数据,而不是只复制引用地址。实现时需要先判断数据类型:基础类型直接返回,引用类型则继续递归创建新的对象或数组,并逐层复制属性。同时,为了处理循环引用问题,通常会配合WeakMap记录已经拷贝过的对象,避免无限递归。本质上,手写深拷贝就是“递归复制结构 + 断开引用关系”。

function deepClone(obj, map = new WeakMap()) { // 1. 基本类型直接返回 if (obj === null || typeof obj !== 'object') { return obj } // 2. 处理循环引用 if (map.has(obj)) { return map.get(obj) } // 3. 创建新对象/数组 const newObj = Array.isArray(obj) ? [] : {} // 4. 缓存当前对象 map.set(obj, newObj) // 5. 递归拷贝 for (const key in obj) { // 过滤原型链属性 if (obj.hasOwnProperty(key)) { newObj[key] = deepClone(obj[key], map) } } return newObj } /* 这段 deepClone 首先判断如果是基本类型或者 null,就直接返回; 如果是对象,就先通过 WeakMap 判断是否已经拷贝过,用来解决循环引用问题。 然后根据原数据是数组还是对象创建对应的新容器,并立刻把原对象和新对象的映射关系存到 WeakMap 中。 最后遍历对象自身属性,对每个属性递归调用 deepClone,实现真正的深层复制。这样拷贝出来的新对象和原对象在嵌套引用上也是相互独立的。 deepClone 中使用 WeakMap 而不是 Map,主要是为了避免内存泄漏。 因为 Map 对 key 是强引用,即使外部对象已经不再使用,只要 Map 中还保存着这个对象作为 key,垃圾回收器就无法释放它。 而 WeakMap 对 key 是弱引用,不会阻止垃圾回收,更适合用来做 deepClone 这种临时缓存的循环引用处理。并且 WeakMap 的 key 只能是对象,也正符合 deepClone 的使用场景。 */

2.手写寄生组合式继承

寄生组合式继承是 JavaScript 中一种比较经典且高效的继承方案,它结合了“原型链继承”和“借用构造函数继承”的优点。实现时,子类通过Parent.call(this)继承父类实例属性,避免属性共享问题;同时通过Object.create(Parent.prototype)继承父类原型方法,从而避免多次调用父类构造函数带来的性能浪费。本质上,它实现了“实例属性独立 + 原型方法复用”,也是 ES6class extends出现前最推荐的继承方式之一。

手写寄生组合式继承的核心是组合“构造函数继承”和“原型继承”两种方式:先通过Parent.call(this)让子类继承父类的实例属性和方法,再通过Object.create(Parent.prototype)创建一个以父类原型为基础的新对象赋值给子类原型,从而实现原型方法复用,并修正constructor指向。这样既避免了引用属性共享的问题,又减少了父类构造函数的重复调用,是 ES5 中比较完善的一种继承实现方案。

function Parent(name) { this.name = name this.colors = ['red', 'blue'] } Parent.prototype.sayName = function () { console.log(this.name) } function Child(name, age) { // 1. 继承父类实例属性 Parent.call(this, name) this.age = age } // 2. 继承父类原型方法 Child.prototype = Object.create(Parent.prototype) // 3. 修正 constructor 指向 Child.prototype.constructor = Child Child.prototype.sayAge = function () { console.log(this.age) }

3.手写数组扁平化

数组扁平化是指将多层嵌套的数组转换成一个一维数组的过程,例如把[1, [2, [3, 4]]]转换为[1, 2, 3, 4]。它的核心思想是“递归展开嵌套结构”,在前端开发中常用于数据处理、树形结构转换以及接口数据整理等场景。实现方式通常包括递归、reduce、扩展运算符以及 ES6 的flat()方法等。

手写数组扁平化的核心是递归遍历数组中的每一项:如果当前元素是数组,就继续递归展开;如果是普通元素,就直接放入结果数组中,最终将多层嵌套结构转换成一维数组。实现时常见的方法有递归、reduce、栈结构以及扩展运算符等,本质上就是“遍历嵌套结构并不断展开”。

function flatten(arr, depth = 1) { if (depth <= 0) { return arr.slice() } const res = [] for (const item of arr) { if (Array.isArray(item)) { res.push(...flatten(item, depth - 1)) } else { res.push(item) } } return res }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/24 1:27:04

别再死记硬背CRF公式了!用Python手写一个BIO命名实体识别Demo,带你直观理解发射与转移矩阵

用Python从零实现CRF&#xff1a;BIO标注中的发射与转移矩阵实战解析 在自然语言处理领域&#xff0c;命名实体识别(NER)是信息抽取的基础任务之一。当我们第一次接触条件随机场(CRF)时&#xff0c;那些复杂的公式和抽象的概率图模型常常让人望而生畏。本文将通过一个完整的Pyt…

作者头像 李华
网站建设 2026/5/24 1:21:22

用AI解决电源最复杂PDN问题的实战设计案例

用AI解决电源最复杂PDN问题的实战设计案例在过去的几年里&#xff0c;我们见证了AI在图像识别、自然语言处理领域的统治。但在硬件物理设计领域&#xff0c;尤其是电源完整性PI和 信号完整性SI这种顶层物理战场上&#xff0c;AI 似乎一直像个门外汉。为什么&#xff1f;因为硬件…

作者头像 李华
网站建设 2026/5/24 1:20:09

Unity Device Simulator:深度解析UI适配调试核心机制

1. 这个“设备模拟器”不是让你在电脑上玩手游的很多人第一次看到Device Simulator&#xff0c;下意识觉得&#xff1a;“哦&#xff0c;Unity里又出了个能预览手机效果的窗口&#xff1f;”——这理解方向就偏了。它根本不是个“截图预览工具”&#xff0c;而是 Unity 编辑器原…

作者头像 李华
网站建设 2026/5/24 1:09:14

cmake和makefile

一、什么是cmake和makefile简单来说&#xff0c;CMake 是一个用来生成 Makefile 的工具。它们是构建 C/C 项目过程中不同层级的工具&#xff0c;通常配合使用&#xff0c;而不是相互替代。&#x1f9f1; Makefile&#xff1a;编译的“施工队”角色&#xff1a; 它是具体的“执行…

作者头像 李华
网站建设 2026/5/24 1:09:11

04-系统技术架构师必备——设计模式在系统架构中的应用

关键词:GoF设计模式、SOLID原则、工厂模式、观察者模式、策略模式、适配器模式、装饰器模式、架构师 设计模式 GoF SOLID原则 系统架构 架构师 面向对象 Java 代码重构 系统技术架构师必备——设计模式在系统架构中的应用 摘要 GoF 23种设计模式是系统技术架构师必须掌握的&…

作者头像 李华