前端面试题

1,Promise构造函数是用来处理异步任务回调函数的一种方案,可代替callback函数
异步任务不会进入主线程而是由浏览器线程执行,执行完毕后会调用主线程的回调函数,promise就是用来处理这个回调函数
async(异步)关键词作用于函数体(主线程同步执行),用来标识函数内部有异步任务,await关键词用于async异步函数内部,用来阻塞线程等异步任务执行完毕再往下执行,await后的代码会打包成微任务,等回调函数返回后,进入主线程处理

状态:等待,成功,失败

2,构造函数
构造函数会自动创建一个空对象
工厂模式的情况下,构造函数相比普通函数可节省内存,普通函数多次调用就会创造一个新的方法副本

3,数组扁平化flat函数
arr.flat()
参数可以数字,或者不传(默认1),或者Infinity扁平化全部层级

4,异步组件:defineAsyncComponent
父组件加载会返回一个占位符,组件加载完成后替换占位符

优:加快初始化时间,按需加载,避免资源浪费
缺:动态导入会发起http请求,不利于浏览器爬取和索引

5,函数声明和函数表达式
函数声明会导致变量提升致作用域顶部,函数表达式是变量定义,重复定义会覆盖同名函数声明和函数表达式

6,vue2和vue3
响应式系统升级、写法更灵活,采用组合式api、diff算法优化Dom渲染性能提升,引入Tree Shaking打包体积更小、ts支持性更好
diff:在vue3数据改变后虚拟Dom生成真实Dom的过程中,对比新旧Vnode节点得出修改的最小单位

7,spa单页应用怎么加快加载速度
1,代码组件化,使用异步加载
2,资源预加载,懒加载,缓存重复使用的资源
3,静态资源使用CDN
4,不要重复请求api
5,循环dom使用有效的key值
6,较大的库使用外部扩展,如lodash
7,页面路由跳转有些页面能缓存就缓存
8,首次加载服务器端渲染快于客户端渲染
9,用户体验上用骨架屏之类的

8,组件传值
1,props和emit
2,provide和inject
3,状态管理(小型项目使用localstrorage或者全局变量)
4,事件总栈eventbus
5,uni.on和uni.emit
6,父传子,ref获取子组件的实例
7,作用域插槽

9生命周期函数

10,盒模型
每个元素都是一个矩形盒子,有外边距,内边距,边框,内容
标准盒模型:日常使用的,高宽为内容
怪异盒模型:高宽为内边距加边框加内容
• box-sizing: content-box; (默认值) - 使用标准盒模型。
• box-sizing: border-box; - 使用怪异盒模型。

11,响应式设计
一套代码适应不同分辨率
使用百分比,媒体查询,使用flex或者grid布局,unocss响应式前缀(sm:p-3,md:p-3)

媒体查询:
/* 超小设备 (手机, 小于 768px) /
/
通常不需要 min-width 查询,因为这是默认的移动样式(Mobile First) */

/* 小型设备 (平板, 768px 及以上) */
@media (min-width: 768px) { … }

/* 中型设备 (笔记本/小桌面, 992px 及以上) */
@media (min-width: 992px) { … }

/* 大型设备 (大桌面, 1200px 及以上) */
@media (min-width: 1200px) { … }

/* 也可以使用 max-width /
@media (max-width: 767px) { … } /
仅对手机生效 */

12,CSS modules
样式合理,实现局部样式,类似vue的scoped
Css modules在编译时转换类名
Scoped在运行时修改类型,类名后添加属性标识

13,js原型链
每个对象都有原型链,如果访问这个对象的一个属性或者方法,这个对象本身没有就会去原型链上原型中逐个往上查找,直到找到或者原型链顶端Object.prototype,比如定义一个数组,使用data.toString(),因为原型链顶端有这个方法,所以可以执行成功

Es6的class 语法糖可以继承原型链
Class son extends father{}

14,js的事件循环Event Loop(无限循环,不会停止)
监听和调度任务,处理高并发的异步任务,保证单线程不会堵塞
先同步任务,微任务(promise回调函数,比如await接口返回后复赋值),再宏任务(settimeout),最后再检查有没有微任务需要执行
(微任务执行完毕,再执行一个宏任务,继续检查有没有微任务,全部任务完成后会进入休眠继续等待下一个进入的任务)
微任务:加急任务
宏任务:普通任务

15,在ts中生成dom
1,h函数生成虚拟节点VNode,render函数把虚拟节点生成真实dom
2,tsx < script setup lang=“tsx”>

16,vue-router
两种模式
hash:url中带#,通过hashchange实现路由切换,兼容性好
history:url正常模式,比较美观,通过pushstate和replacestate实现,需要服务器端支持,避免刷新出现404,利于seo优化(浏览器搜索引擎不解析url的#后内容)

17,导航守卫
路由跳转执行的钩子函数
router.beforeEach路由跳转前的前置守卫,用于验证登录,权限,页面是否存在等
router.afterEach路由跳转后的后置守卫

18,状态管理:管理全局共享数据和相应操作数据的方法
Pinia更轻量级,支持ts,写法使用组合式,默认支持模块化

19, vite打包体积过大
1,使用tree shaking
2,按需引入
3,开发环境需要的插件安装在开发配置中,不需要安装到生产配置
4,图片等静态资源使用cdn
5,配置高效的压缩算法
6,配置代码分割策略

20,Websocket
建立在http请求上的一个特殊请求
步骤:
1,建立连接
1.1,客户端握手
客户端发起一个new Websocket(url)请求,请求头带两个信息,标识是Websocket请求。
Upgrade: websocket // 将协议升级为Websocket
Connection: Upgrade // 此次连接需要转换协议
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ== // 随机Base64 密钥,由浏览器生成
Sec-WebSocket-Version: 13 // 使用的 WebSocket 协议版本(13是现行标准)

1.2,服务器响应
服务器支持websocket则返回101响应,并同样返回这两个标识
Upgrade: websocket // 同意升级为Websocket
Connection: Upgrade // 确认转换协议

2,数据传输
握手成功后TCP保持打开,通过数据帧进行通信
数据帧头特别小,这是他能保证实时通信不延迟的原因

3,心跳机制
心跳机制用来检查websocket是否正常连接,服务器端向客户端发请求

前端实现
1,创建连接
// 使用 ‘ws://’ 用于非加密连接(开发环境)
// 使用 ‘wss://’ 用于加密连接(生产环境,等同于 HTTPS)
const socket = new WebSocket(‘wss://your-websocket-server.com/chat’);
2,使用websocket方法获取服务器端数据或者向服务器端传递数据

3,完毕后在onUnmounted 中使用close方法清理连接

21,watch
监听多个属性
watch(
[() => state.user.name, () => state.user.age],
([newName, newAge], [oldName, oldAge]) => {
console.log(‘name 或 age 变化了’);
}
);

22,普通函数与箭头函数的区别
写法不一样,this指向不同,普通函数可作为构造函数,箭头函数不行
普通函数不return会返回undefined

22,typeof返回
类型 返回值
Undefined “undefined”
Null “object” (历史遗留问题)
Boolean “boolean”
Number “number”
BigInt “bigint”
String “string”
Symbol “symbol”
Function “function”
其他对象 “object”

23,组件透传

24,实现v-model
一,使用update:modelValue

<input
type=“text”
:value=“modelValue”
@input=“$emit(‘update:modelValue’, $event.target.value)”
/>

二,使用defineModel(vue3.3+)

const modelValue = defineModel()

// 带类型和默认值
const modelValue = defineModel(‘默认值’)

// 多个 v-model
const firstName = defineModel(‘firstName’, { default: ‘’ })
const age = defineModel(‘age’, { default: 0 })

25,es6

26,nextTick
响应式数据更新后,会生成一个异步的微任务加入到队列,等待事件循环调度主线程执行这个微任务,nextTick就是一个特殊的promise异步任务,在等待数据更新的微任务执行完毕后再执行,所以他能保证获取到最新的Dom

27,闭包

闭包就是能够读取其他函数内部变量的函数,或者说是一个函数和其周围状态

原理:
函数在执行时,会创建一个作用域链。通过作用域链,内部函数可以访问外部函数的变量,即使外部函数已经执行完毕,只要内部函数还在被引用,外部函数的变量就不会被垃圾回收,从而被“封闭”在内部函数中。

28,作用域链
作用域:作用域就是变量和函数的可访问范围

作用域链:当在某个作用域内访问一个变量或函数时,JavaScript 引擎会遵循一个从当前作用域到外层作用域逐级查找的机制。这个查找路径就像一条链子,所以我们称之为作用域链。

29,深拷贝浅拷贝
“浅拷贝时,嵌套对象的内存地址指向同一个;深拷贝时,所有层次的内存地址都是不同的。”

浅拷贝,展开运算符{…obj},object.assign
浅拷贝只有嵌套对象的会指向同一个内存地址

深拷贝,cloneDeep

30,使用unocss实现媒体查询响应式样式
使用响应式前缀

31,组件开发
• 单一职责 - 每个组件只关注一个特定功能
• 可复用性 - 通过props和插槽提供灵活性
• 可维护性 - 清晰的接口和良好的文档
• 性能优化 - 合理使用响应式数据和生命周期

32,怎么实现一个vue3的路由
创建一个路由文件,实现路由配置,创建路由,然后挂载到main.ts中,页面使用router-link渲染路由链接,使用router- view显示路由页面

动态路由:
1,定义基础的路由文件,404,登录页等
2,从后端获取路由数据(main.ts或者apo.vue中预加载,路由守卫中按需加载)
3,转换路由格式{path,component,name,meta}
4,添加动态路由:router.addRoute(route)
5,路由守卫控制权限:router.beforeEach
6,渲染菜单:路由链接:router-link 路由视图:router-view

也可以使用component 标签实现,不需要3,4,6步

设置路由缓存:

</router-view>

33, vue3插槽
1,默认插槽
子组件component1:‹slot›默认内容</slot>
父组件:
使用默认内容:<component1/>
传入自定义内容:
<component>
自定义内容
<component/>

2,具名插槽:子组件通过插槽向父组件传递数据
子组件:
默认内容

父组件:

<template v-slot:插槽名称>
插入的内容

<template #插槽名称>
插入的内容

3,作用域插槽

◦	子组件定义:
{{ user.name }} - {{ user.email }}

父组件使用:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值