Skip to main content

· 14 min read

常见面试题

vite怎么识别的.vue文件, 怎么识别icon字体文件

Vite 中内置了一个名为 @vitejs/plugin-vue 的插件,该插件可以解析 .vue 文件并将其转换为 JavaScript 代码。该插件使用了 Vue 官方提供的 vue-template-compiler 库来进行 .vue 文件的编译,它可以将 .vue 文件中的 template、script 和 style 标签中的代码分别提取出来进行编译,并最终生成对应的 JavaScript 代码。

在安装了 @vitejs/plugin-icons 插件之后,我们只需要在代码中使用相应的字体文件,然后在 HTML 中引入 Web Font Loader 即可。

为什么react的hook只能写在函数内

因为函数组件没有实例,所以 React 的 Hook 需要在函数组件内部调用,而不能在类组件或普通函数中调用。这是因为 Hook 需要依赖 React 内部的 Fiber 架构来实现状态管理和生命周期的调度,并且需要在函数组件内部建立起与组件的联系,从而让组件能够响应状态变化和更新渲染。

优化打包做了哪些措施

  • 代码拆分:将代码拆分成更小的块,可以让用户更快地加载页面并减少初始下载时间。Webpack 提供了多种代码拆分技术,如动态导入和异步加载等。

  • 按需加载:按需加载是一种延迟加载技术,可以在需要时再加载资源。Webpack 提供了多种按需加载技术,如使用 React.lazy、Suspense 和 import() 等。

  • 使用Tree Shaking:Tree Shaking 是一种在打包过程中剔除无用代码的技术,可以减小打包后的文件大小。Webpack 4 中默认开启了 Tree Shaking 功能。

  • 压缩代码:通过压缩代码可以减小文件大小,提高加载速度。Webpack 可以使用 UglifyJS 插件来压缩代码。

  • 使用缓存:缓存可以减少重复的网络请求和资源加载,提高用户体验。Webpack 可以使用缓存来提高打包效率。

  • 使用CDN加速:使用 CDN 加速可以提高资源的加载速度和可靠性,减少服务器压力。

  • 拆分第三方库:将第三方库和应用程序代码分开打包,可以提高打包效率和资源利用率。

  • 使用Scope Hoisting:Scope Hoisting 是一种优化 JavaScript 代码的技术,可以减小打包后的文件大小和加载时间。

  • 优化图片:对图片进行压缩和转换,可以减小文件大小,提高加载速度。

大文件上传 可以做那些优化

  • 分块上传:将大文件拆分成多个小块,每个小块上传完成后再进行下一个小块的上传,可以提高上传速度和上传的可靠性。通常将每个块的大小设为1MB到10MB之间比较合适。

  • 断点续传:当上传过程中出现网络断开或浏览器崩溃等问题时,可以记录已经上传的块号和偏移量,下次上传时从上次中断的位置继续上传,可以避免重复上传已经上传过的块,提高上传的效率。

  • 并发上传:可以同时上传多个块,从而提高上传速度。但是在实现并发上传时需要注意,由于服务器有可能会限制并发上传的数量,因此需要进行一些限制和控制。

  • 压缩文件:可以使用压缩算法对文件进行压缩,减小文件大小,从而提高上传速度和减少网络流量消耗。但是需要注意,压缩算法可能会带来一定的压缩和解压缩时间开销,因此需要进行权衡。

  • 优化网络传输:可以使用一些网络传输优化技术,如分片传输、流式传输、数据压缩等,可以减少传输时间和网络带宽消耗。

  • 限制上传速度:可以在客户端限制上传速度,从而避免过度占用网络带宽,导致其他网络请求受阻。但是需要注意,限制上传速度可能会影响用户体验。

  • 优化服务器接收:在服务器端可以对接收到的数据进行一些处理和优化,如分块存储、内存映射、并发接收等,可以提高上传的效率和稳定性。

Vue和React区别

Vue 和 React 是两个非常流行的前端框架。它们都具有以下特点:

  • 都是基于组件化开发思想的框架。
  • 都支持虚拟 DOM 技术,提高性能。
  • 都有良好的生态系统和社区支持。 但是,它们也有一些不同点:
  1. 模板语法不同 Vue 采用的是基于 HTML 的模板语法,可以方便地创建复杂的 UI。而 React 则使用 JSX,它允许在 JavaScript 代码中编写 HTML 标签,使得组件的代码更加直观和易于维护。

  2. 状态管理不同 Vue 使用的是响应式的数据绑定,数据更新时会自动触发视图的重新渲染。而 React 则使用了单向数据流的思想,数据更新需要通过显式地调用 setState 方法来触发组件的重新渲染。在处理大型应用程序时,Vue 的响应式数据绑定可能会导致性能问题。

  3. 生命周期不同 Vue 的生命周期钩子函数比较多,包括 beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、beforeDestroy 和 destroyed 等。而 React 只有 componentDidMount、componentDidUpdate、componentWillUnmount 等几个生命周期函数,使用起来相对简单。

  4. 组件复用不同 在 Vue 中,组件的复用比较简单,可以直接使用 components 属性来定义一个全局组件,然后在模板中使用。而 React 则需要使用高阶组件、组合模式等技术来实现组件的复用。

总的来说,Vue 更加注重开发效率和开发体验,而 React 则更加注重灵活性和可定制性。选择使用哪个框架,需要根据具体的项目需求和开发团队的技术栈来进行权衡。

Vue3和React的hook又什么区别

Vue3 和 React 的 Hook 在概念和实现上有一些相似之处,都提供了一种新的组件复用方式,可以让开发者在函数组件中使用状态和生命周期函数等功能,从而提高了组件复用性和代码的可读性。

但是,在具体的实现方式上,Vue3 和 React 的 Hook 也存在一些区别:

  1. Hook 的命名方式不同 Vue3 中使用的是 use 前缀,如 useSetup、useComputed 等,而 React 中使用的是 use 前缀加上对应功能的名称,如 useState、useEffect 等。

  2. Hook 的使用方式不同 在 Vue3 中,可以在 setup 函数中使用 ref、reactive、computed 等 API 来实现组件的状态管理和计算属性等功能。而在 React 中,可以在函数组件中使用 useState、useEffect、useContext 等 Hook 来实现类似的功能。

  3. Hook 的实现原理不同 Vue3 的 Hook 是通过在组件实例中存储一个 hooks 对象来实现的,每个 useXXX 函数都会在 hooks 对象中添加一个相应的钩子函数,以便在组件更新时调用。而 React 的 Hook 则是基于 Fiber 架构的,通过链表形式来记录每个组件的状态和副作用,并在组件更新时进行相应的调度和更新。

总的来说,Vue3 和 React 的 Hook 在概念和实现上都有一些相似之处,但是具体的使用方式和实现原理都有所不同。选择使用哪种框架和技术,需要根据具体的项目需求和团队技术栈来进行权衡。

前端性能监控

前端监控是指通过在前端代码中埋点,采集用户行为、性能数据等信息,进行数据分析和异常监控,以提升用户体验和应用程序质量。

以下是一些前端监控常用的技术:

  1. 错误监控:捕获代码执行错误、资源加载错误等,通过前端日志收集工具(如sentry)上报错误信息。

  2. 性能监控:记录关键性能指标(如页面加载时间、接口请求时间、渲染时间等),通过前端性能监控工具(如FMP、WebPagetest等)进行数据收集和分析。

  3. 用户行为监控:通过埋点统计用户的行为数据(如点击、滚动、页面浏览等),进行数据分析和用户画像。

  4. 异常监控:监控系统异常、服务器异常等,通过日志、邮件等方式通知开发人员。

具体实现可以参考以下几种方案:

  • 自研监控:手动编写代码实现监控功能,但需要编写大量代码和维护成本较高。

  • 使用第三方监控工具:如前文提到的sentry、FMP、WebPagetest等,可以快速接入并提供多样化的监控指标。

  • 利用前端框架或库的监控能力:如Vue、React等框架提供的错误监控能力、Axios等库提供的请求拦截能力等。

cookie和localstorage的同源策略有什么不同

Cookie和LocalStorage都是浏览器提供的用于存储数据的机制,但它们在同源策略上有一些不同。

Cookie是一种用于存储数据的机制,它可以被浏览器自动发送到服务器,因此可以用于实现用户登录等场景。但是,Cookie的同源策略比较严格,只有在同一域名下的网页才能够共享Cookie,因此不同域名下的网页之间无法共享Cookie。

LocalStorage也是一种用于存储数据的机制,它可以将数据存储在浏览器本地,以供后续使用。LocalStorage的同源策略比Cookie宽松一些,同一协议、同一端口号和同一主机名的网页之间可以共享LocalStorage中的数据,因此即使是不同域名下的网页也可以共享LocalStorage中的数据。

总的来说,Cookie和LocalStorage都是用于存储数据的机制,但是它们在同源策略上有一些不同,开发者在使用时需要注意它们的区别。

· 3 min read
Lvxl

考点: this

window.onload = function() {
var length = 1;
function fn() {
console.log(this.length)
}
var obj = {
length: 100,
action: function(callback) {
callback();
arguments[0]();
}
}

var arr = [1,2,3,4]
obj.action(fn, ...arr)

// 结果:
}

考点 事件循环


setTimeout(() => {
console.log(100)
},0)

new Promise((resolve, reject) => {
resolve()
}).then(() => {
console.log(200)
})

function f() {
console.log(300)
}

async function f2 () {
await f()
console.log(400)
}
f2()


// 300 -> 200 -> 400 -> 100
// 思路:
// 1. settimeout100 加入到宏任务队列
// 2. promise.then() 加入到微任务队列
// 3. f2() 执行
// 4. await f()执行 输出 300
// 5. await 下面的 400 加入到微任务队列
// 6. 开始下一次循环 先执行微任务队列先进先出原则 输出 200
// 7. 继续执行微任务队列里面的任务 400
// 8. 最后执行宏任务 100

考点 作用域


var a = 10
var obj = {
a: 99,
f: test
}
function test() {
console.log(a)
a = 100
console.log(this.a)
var a
console.log(a)
}
obj.f()


var a = 10
function f1 () {
var b = 2 *a:
var a = 20;
var c = a + 1
console.log(b)
console.log(c)
}
f1()

// go: a f1 => undefind
// vo: b a c
// b = 2 * undefind => NaN
// a = 20
// c = 20 + 1
// b = NaN
// c = 21

考点: js计算精度问题

// 对于这个问题,一个直接的解决方法就是设置一个误差范围,通常称为“机器精度”。对JavaScript来说,这个值通常为2-52,在ES6中,提供了Number.EPSILON属性,而它的值就是2-52,只要判断0.1+0.2-0.3是否小于Number.EPSILON,如果小于,就可以判断为0.1+0.2 ===0.3

function numberepsilon(arg1,arg2){
return Math.abs(arg1 - arg2) < Number.EPSILON;
}

console.log(numberepsilon(0.1 + 0.2, 0.3)); // true

考点: 二叉树 将[3,9,null,null,15,7] 转为树形结构

// 1. 定义一个树节点类,包含节点值、左子节点和右子节点:
class TreeNode {
constructor(val) {
this.val = val
this.left = null
this.right = null
}
}
// 2.定义一个函数,接受一个数组作为参数,并返回构建好的树的根节点:
function buildTree(arr) {
if (!arr || !arr.length) return null;

// 创建根节点
const root = new TreeNode(arr[0])
// 层序遍历创建树
const queue = [root]
let i = 1;
while(queue.length > 0 && i <arr.lenght) {
const node = queue.shift()
//左子节点
if(arr[i] !== null) {
const left = new TreeNode(arr[i]);
node.left = left
queue.push(left)
}
i++;
}
}

(a == 1 && a == 2 && a == 3)


let obj = {
value: 1,
get a() {
return this.value++;
}
};

console.log(a == 1 && a == 2 && a == 3); // 输出 true

对象的扁平化