前端面试手册
岗位职责:
1.熟悉公司业务,能独立高效高质地完成任务,负责功能的开发、测试、上线、维护;
2.负责推动、优化前端基础架构、组件抽象,提升开发效率;
3.关注前端前沿技术发展,能够将新知识传递给团队,并且转化到潜在项目中。
4.负责提升研发和运营效率的通用组件、工具和平台能力的开发工作;
5.负责前端核心页面性能优化,打造良好的用户体验
岗位要求
- 三年以上前端领域开发经验,参与过系统核心功能的模块设计与开发,有参与过大型项目开发,并熟悉整体架构和设计原理;;
- 熟悉W3C标准,熟悉ES5、ES6;
- 精通html5和css3,熟悉响应式web设计技术,对Web标准和标签语义化有深入理解;
- 熟练使用Vue,React,Flutter,UniApp,Electron等框架之一;
- 精通JavaScript、Ajax等JS技术,对Javascript面向对象编程具有深入的了解,理解工程化思想,对构建和持续集成有一定认识;
- 熟悉前端工程化工具,如CI/CD流水线、Gulp、webpack、Rollup、Vite等;
- 熟悉node.js,以及Web服务端开发优先
- 熟练使用各种调试、抓包工具,能独立分析、解决和归纳问题;
- 有较强的敬业精神,责任心及良好的沟通能力和团队合作精神,热爱探索新技术
- 加分项:
- 有客户端/跨端技术(Android/iOS/Flutter/RN/Electron等)开发经验;
- 在网页中注入JS,定制功能。
- 基础
- 什么是闭包,以及如何/为什么使用闭包?
闭包是在函数返回后保持对函数中变量的访问的一种方式。闭包通常用于数据隐私、封装和创建具有持久状态的函数。
2. 描述一下 Array.forEach() 循环和 Array.map() 方法之间的主要区别以及为什么您会选择其中一种方法?
主要区别在于 Array.forEach() 迭代数组的每个元素并对每个元素执行操作,但它不返回新数组。
另一方面,Array.map() 通过将函数应用于原始数组的每个元素来创建新数组。当您想要对每个元素执行操作而不返回新数组时,您可以选择 Array.forEach() ;当您需要将数组转换为新数组时,您可以选择 Array.map() 。
3. 描述事件冒泡
事件冒泡是一种机制,其中内部元素中发生的事件通过 DOM 层次结构中的父元素传播或"冒泡"。它从最里面的元素开始,一直持续到文档级别,一路触发附加到每个父元素的事件处理程序。
4. 解释事件委托
事件委托是一种技术,您无需将事件侦听器附加到各个元素,而是将单个事件侦听器附加到将为其子元素处理事件的父元素。当您有大量元素或动态添加元素时,此方法非常有用,因为它可以提高性能并减少内存消耗。
5. CORS 代表什么以及它解决什么问题?
CORS 代表跨源资源共享。它是一种机制,允许从资源来源域之外的另一个域请求网页上的资源。CORS 解决了浏览器强制执行的同源策略,该策略可防止脚本出于安全原因向不同域发出请求。
6. 解释let、var和const之间的区别
let 和 const 是在 ES6 中引入的,而 var 从 JavaScript 的早期版本开始就可用了。
let 和 const 具有块作用域,这意味着它们仅限于声明它们的块(例如,在大括号内)。var 具有函数作用域,这意味着它可以在声明它的整个函数中访问。
const 与 let 类似,但用于在初始分配后不应重新分配的变量
7. 匿名函数的典型用例是什么?
匿名函数,也称为函数表达式,是在没有指定名称的情况下定义的函数。
它们通常用于需要一个函数作为另一个函数的参数的情况或创建自调用函数时。
匿名函数允许更简洁的代码,并且可以通过使函数定义更接近其用法来帮助提高代码可读性。
8. 解释同步函数和异步函数之间的区别。
同步函数逐步执行,每一行都等待前一行完成。异步函数允许在上一步完成之前执行到下一步。异步函数通常用于非阻塞操作。
9. 函数式编程与面向对象编程相比有何优缺点?
函数式编程避免共享状态和可变数据,使代码更易于阅读和调试。面向对象编程依赖于共享的主状态,这可能会导致复杂性。
函数式编程还促进不变性并支持高阶函数,而面向对象编程则强调封装和多态性。
10. 集合与数组有什么区别?
集合不能包含重复值,而数组可以。当唯一性很重要时,集合很有用。
11. 您能解释一下从您输入网站 URL 到其在屏幕上完成加载的整个过程吗?
当您输入网站的 URL 时,浏览器会执行一系列步骤,包括 DNS 解析、建立 TCP 连接、发送 HTTP 请求、接收 HTTP 响应、解析和渲染网站内容以及加载其他资源(如果需要)。
12. 如何识别浏览器中的内存泄漏?
识别浏览器中的内存泄漏涉及监视一段时间内的内存使用情况并分析堆快照。Chrome DevTools 等工具提供内存分析功能来跟踪内存分配、检测未使用的对象以及识别可能指示内存泄漏的长生命周期对象。
13. HTTP GET 和 POST 请求有什么区别?
HTTP GET 和 POST 请求都用于将数据从客户端传输到服务器。但是,GET 请求包括附加到 URL 的请求参数,而 POST 请求包括消息正文中的请求参数。POST 请求对于传输敏感数据更加安全,因为参数在 URL 中不直接可见。
14. 处理异步调用 的方法有哪些?各有什么优缺点?
回调、promise、await 、async
回调提供了处理异步调用的传统方法,但可能导致回调地狱并使代码难以阅读。
Promise 提供了更简洁的语法,并允许通过链接和 catch 块等功能更好地处理错误。
Async/await 是最近添加的功能,它通过使用异步函数和等待 Promise 来简化异步代码,使代码看起来更加同步且更易于理解。
15.解释一下 MVVM?
View 层是视图层,也就是用户界面。前端主要由 HTML 和 CSS 来构建 。
Model 层是指数据模型,泛指后端进行的各种业务逻辑处理和数据操控,对于前端来说就是后端提供的 api 接口。
ViewModel 层是由前端开发人员组织生成和维护的视图数据层。在这一层,前端开发者对从后端获取的 Model 数据进行转换处理,做二次封装,以生成符合 View 层使用预期的视图数据模型
16. rpx、px、em、rem、%、vh、vw的区别是什么?
1.rpx 相当于把屏幕宽度分为750份,1份就是1rpx
2.px 绝对单位,页面按精确像素展示
3.em 相对单位,相对于它的父节点字体进行计算
4.rem 相对单位,相对根节点html的字体大小来计算
5.% 一般来说就是相对于父元素
6.Vh 视窗高度,1vh等于视窗高度的1%
7.Vm 视窗宽度,1vw等于视窗宽度的1%
二. React 面试题
1. Prop 和 State 有什么区别?
props 和 state 都是 React 组件中使用的普通 JavaScript 对象。props 从父组件传递到子组件,用于组件内不会更改的数据。另一方面,状态在组件本身内进行管理,并且可以使用 setState 方法进行更新。props 是不可变的,而 state 可以更新。
2. React 组件中有哪些生命周期方法?
componentDidMount、componentWillMount、componentWillUpdate、componentDidUpdate、shouldComponentUpdate 和 componentWillReceiveProps。
这些方法允许您在组件生命周期的不同阶段执行操作,例如初始化数据、更新 UI 或处理 prop 更改。
3. 虚拟 DOM 和 Shadow DOM 实现。React 协调是如何工作的?
React 使用虚拟 DOM 来高效地更新和渲染组件。它创建实际 DOM 的轻量级表示,并执行比较算法来确定更新真实 DOM 所需的最小更改集。React 的协调过程使虚拟 DOM 更改与实际 DOM 保持一致,从而优化渲染。
三. vue面试题
1. 说说你对 SPA 单页面的理解,它的优缺点分别是什么?
SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。
优点:
- 用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;
- 基于上面一点,SPA 相对对服务器压力小
- 前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理
·
缺点:
- 初次加载耗时多:为实现单页 Web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统一加载,部分页面按需加载;
- 前进后退路由管理:由于单页应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理
- SEO 难度较大:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势
- v-show 与 v-if 有什么区别?
v-if 是真正的条件渲染,为真才会开始渲染条件块
v-show 元素总是会被渲染,并且基于 CSS 的 "display" 属性进行切换。
所以,v-if 适用于在运行时很少改变条件,不需要频繁切换条件的场景;v-show 则适用于需要非常频繁切换条件的场景。
- 怎样理解 Vue 的单向数据流?
所有的 prop 都使得其父子 prop 之间形成了一个单向下行绑定:父级 prop 的更新会向下流动到子组件中,但是反过来则不行。这样会防止从子组件意外改变父级组件的状态,从而导致你的应用的数据流向难以理解。额外的,每次父级组件发生更新时,子组件中所有的 prop 都将会刷新为最新的值。这意味着你不应该在一个子组件内部改变 prop。如果你这样做了,Vue 会在浏览器的控制台中发出警告。子组件想修改时,只能通过 $emit 派发一个自定义事件,父组件接收到后,由父组件修改。
- computed 和 watch 的区别和运用的场景?
computed: 是计算属性,依赖其它属性值,并且 computed 的值有缓存,只有它依赖的属性值发生改变,下一次获取 computed 的值时才会重新计算 computed 的值;
watch: 更多的是「观察」的作用,类似于某些数据的监听回调 ,每当监听的数据变化时都会执行回调进行后续操作;运用场景:
当我们需要进行数值计算,并且依赖于其它数据时,应该使用 computed,因为可以利用 computed 的缓存特性,避免每次获取值时,都要重新计算;
当我们需要在数据变化时执行异步或开销较大的操作时,应该使用 watch,使用 watch 选项允许我们执行异步操作 ( 访问一个 API ),限制我们执行该操作的频率,并在我们得到最终结果前,设置中间状态。这些都是计算属性无法做到的。
- 谈谈你对 Vue 生命周期的理解?
Vue 实例完整的生命周期,从开始创建、初始化数据、编译模版、挂载 Dom -> 渲染、更新 -> 渲染、卸载等一系列过程,我们称这是 Vue 的生命周期。
(2)各个生命周期的作用生命周期描述
beforeCreate 组件实例被创建之初,组件的属性生效之前
created 组件实例已经完全创建,属性也绑定,但真实 dom 还没有生成,$el 还不可用
beforeMount 在挂载开始之前被调用:相关的 render 函数首次被调用
mounted el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用该钩子
beforeUpdate 组件数据更新之前调用,发生在虚拟 DOM 打补丁之前
update 组件数据更新之后
activited keep-alive 专属,组件被激活时调用
deadctivated keep-alive 专属,组件被销毁时调用
beforeDestory 组件销毁前调用
destoryed 组件销毁后调用
6. Vue 的父组件和子组件生命周期钩子函数执行顺序?
Vue 的父组件和子组件生命周期钩子函数执行顺序可以归类为以下 4 部分:
加载渲染过程·
父 beforeCreate -> 父 created -> 父 beforeMount -> 子 beforeCreate -> 子 created -> 子 beforeMount -> 子 mounted -> 父 mounted
·
子组件更新过程
父 beforeUpdate -> 子 beforeUpdate -> 子 updated -> 父 updated
·
父组件更新过程
父 beforeUpdate -> 父 updated
·
销毁过程
父 beforeDestroy -> 子 beforeDestroy -> 子 destroyed -> 父 destroyed
- 在什么阶段才能访问操作DOM?
在钩子函数 mounted 被调用前,Vue 已经将编译好的模板挂载到页面上,所以在 mounted 中可以访问操作 DOM。
7. v-model 的原理?
我们在 vue 项目中主要使用 v-model 指令在表单 input、textarea、select 等元素上创建双向数据绑定,我们知道 v-model 本质上不过是语法糖,v-model 在内部为不同的输入元素使用不同的属性并抛出不同的事件:
text 和 textarea 元素使用 value 属性和 input 事件;
checkbox 和 radio 使用 checked 属性和 change 事件;
select 字段将 value 作为 prop 并将 change 作为事件。
·
- Vue 组件间通信有哪几种方式?
3 类通信:父子组件通信、隔代组件通信、兄弟组件通信
1)props / $emit 适用 父子组件通信
2)ref 与 $parent / $children 适用 父子组件通信
3)EventBus ($emit / $on) 适用于 父子、隔代、兄弟组件通信
4)attrs/listeners 适用于 隔代组件通信
5)provide / inject 适用于 隔代组件通信
8. vue-router 路由模式有几种?
路由模式:hash、history、abstract,
hash: 使用 URL hash 值来作路由。支持所有浏览器,包括不支持 HTML5 History Api 的浏览器;
history : 依赖 HTML5 History API 和服务器配置。具体可以查看 HTML5 History 模式;
abstract : 支持所有 JavaScript 运行环境,如 Node.js 服务器端。如果发现没有浏览器的 API,路由会自动强制进入这个模式.
9. 你有对 Vue 项目进行哪些优化?
1)代码层面的优化
v-if 和 v-show 区分使用场景
computed 和 watch 区分使用场景
v-for 遍历必须为 item 添加 key,且避免同时使用 v-if
长列表性能优化
事件的销毁
图片资源懒加载
路由懒加载
第三方插件的按需引入
优化无限列表性能
服务端渲染 SSR or 预渲染
·
2)Webpack 层面的优化
Webpack 对图片进行压缩
减少 ES6 转为 ES5 的冗余代码
提取公共代码
模板预编译
提取组件的 CSS
优化 SourceMap
构建结果输出分析
Vue 项目的编译优化
·
3)基础的 Web 技术的优化
开启 gzip 压缩
浏览器缓存
CDN 的使用
使用 Chrome Performance 查找性能瓶颈
·
10. vue3.0 特性你有什么了解的吗?
1)监测机制的改变
2)模板
3)对象式的组件声明方式
四.U niApp面试题
1. 如何进行页面跳转?
可以使用uni.navigateTo、uni.redirectTo和uni.reLaunch等方法进行页面跳转。
uni.navigateTo可以实现页面的普通跳转,
uni.redirectTo可以实现页面的重定向跳转,
uni.reLaunch可以实现关闭所有页面,打开到应用内的某个页面。
2 .如何进行数据绑定?
可以使用双花括号{{}}进行数据绑定,将数据动态展示在页面上。
3. 如何发送网络请求?
使用uni.request方法发送网络请求,通过设置url、method、data等参数来实现不同的请求。
4. 如何进行数据缓存?
使用uni.setStorageSync方法进行数据缓存,将数据存储到本地缓存中。
5 .如何进行微信支付?
使用uni.requestPayment方法进行微信支付,通过设置支付参数来实现支付功能。
6 .如何进行图片的懒加载?
使用uni.lazyLoadImage组件实现图片的懒加载,将图片的src属性设置为需要加载的图片地址。
7 .如何实现页面跳转?
使用uni.navigateTo方法实现页面跳转,通过设置url参数来指定跳转的页面路径。
8 .如何实现页面间的数据传递?
可以使用uni.navigateTo方法的url参数中添加query参数来实现页面间的数据传递。
9.选择U ni A pp 作为跨平台开发的优缺点 是什么?
优点:
1.跨平台开发: UniApp 允许你在一个代码库中编写应用,并将其编译成多个不同平台的应用,减少了开发成本和维护成本。
2.基于 Vue.js: 如果你熟悉 Vue.js,就能很容易上手 UniApp。Vue.js 的组件化开发和数据绑定特性在 UniApp 中也得以保留。
3.丰富的组件库: UniApp 提供了丰富的组件库,包括跨平台和特定平台的组件,方便快速开发应用。
4.性能优化: UniApp 会根据不同平台进行代码优化,同时也支持一些性能优化的特性,如懒加载、图片压缩等。
5.快速原型开发: 使用 Vue.js 的响应式设计,你可以快速创建原型,并在不同平台上进行测试,加速开发迭代。
6.统一的 API 接口: UniApp 提供了统一的 API 接口,让你可以在不同平台上调用相同的接口,简化了代码编写。
7.插件扩展: UniApp 支持插件扩展,你可以通过插件来增加功能,如地图、支付等。
8.生态系统: UniApp 有一个不断发展的社区和生态系统,可以分享经验、解决方案和开源组件。
缺点:
1.平台差异: 尽管 UniApp力求提供平台无关的代码,但不同平台的差异还是会存在,可能需要做一些平台特定的调整和兼容。
2.灵活度受限: 为了实现跨平台兼容,有时可能会限制一些平台特定的功能,降低了部分灵活度。
3.依赖编译: 由于需要将代码编译成不同平台的代码,开发过程中可能需要依赖 UniApp 的编译过程,一些开发者可能会感到束缚。
4.性能问题: 尽管 UniApp 进行了性能优化,但在某些复杂场景下,可能会存在性能问题,需要注意优化。
5.学习成本: 如果你之前没有使用过 Vue.js,上手 UniApp 需要学习 Vue.js 的基本概念和语法。
6.扩展性限制: 对于一些复杂的功能和需求,可能需要额外的工作来进行扩展和定制。
10. 页面生命周期
-
onLoad:首次进入页面加载时触发,可以在 onLoad 的参数中获取打开当前页面路径中的参数。
-
onShow:加载完成后、后台切到前台或重新进入页面时触发
-
onReady:页面首次渲染完成时触发
-
onHide:从前台切到后台或进入其他页面触发
-
onUnload:页面卸载时触发
-
onPullDownRefresh:监听用户下拉动作
-
onReachBottom:页面上拉触底事件的处理函数
-
onShareAppMessage:用户点击右上角转发