前端面试基础知识整理【Day-7】

目录

前言

Vue-Router篇

1.Vue-Router导航守卫的完整执行流程

2.为什么beforeRouteEnter访问不到this

Vite篇

1.Vite为什么比Webpack快

2.什么是HMR(热更新)

3.虚拟DOM一定比真实DOM快吗

手写代码篇

1.手写数组扁平化flat

2.手写Promise.retry(请求重试)


前言

前端面试基础知识整理【Day-1】-CSDN博客

前端面试基础知识整理【Day-2】-CSDN博客

前端面试基础知识整理【Day-3】-CSDN博客

前端面试基础知识整理【Day-4】-CSDN博客

前端面试基础知识整理【Day-5】-CSDN博客

前端面试基础知识整理【Day-6】-CSDN博客

Vue-Router篇

1.Vue-Router导航守卫的完整执行流程

导航守卫流程一句话总结:"旧组件离开 -> 全局检查 -> 路由检查 -> 新组件进入"

假设从A页面跳转到B页面,路由守卫执行顺序如下:

  1. 失活:beforeRouteLeave(在失活组件中调用)
  2. 全局:router.beforeEach
  3. 重用:beforeRouteUpdate(如果组件被复用则调用它)
  4. 路由独享:beforeEnter
  5. 解析:解析异步路由组件
  6. 组件内:beforeRouteEnter(在被激活的组件里调用)
  7. 全局:router.beforeResolve(所有组件解析完)
  8. 全局:router.afterEach(跳转结束)

2.为什么beforeRouteEnter访问不到this

守卫执行时,新组件的实例还没有被创建,beforeRouteEnter是在导航之前被调用的,此时实例都没有被new出来,自然没有this

但是在beforeRouteEnter的next函数中,支持传入回调,这也是唯一一个支持在next中传递回调的守卫:

javascript 复制代码
beforeRouteEnter(to, from, next) {
  next(vm => {
    // 这里的 vm 就是组件实例
    console.log(vm.someData); 
  });
}

Vite篇

1.Vite为什么比Webpack快

核心区别在于"开发环境 "的启动方式热更新机制

启动一个项目时,ViteWebpack的区别如下:

Webpack

  • 必须先打包整个项目,构建依赖图,才能启动服务器
  • 项目越大,启动越慢

Vite

  • 不需要打包,它直接启动服务器,利用浏览器原生的ES Module能力
  • 当浏览器请求import时,Vite按需编译文件返回给浏览器
  • 启动速度几乎是瞬间的

对于文件的热更新速度,区别如下:

  • Webpack:修改一个文件,需要重新构建该模块及其依赖链,项目大了会有延迟
  • Viet:修改文件后,只需让浏览器重新请求该文件编译后模块即可,热更新速度几乎不变

而在生产环境中,Vite使用Rollup打包,因为浏览器对大量嵌套ESM的网络请求性能依然不佳,此时两者的速度差异不如开发环境明显

2.什么是HMR(热更新)

HMR在应用运行时,只替换变更的模块,而不是刷新整个页面,从而保留应用的状态

底层原理(以Webpack为例,简要版):

  1. 监听:监听文件变化
  2. 构建:文件变动,重新编译
  3. 推送:向浏览器推送更新消息
  4. 请求:浏览器向服务器请求更新清单
  5. 替换:将旧模块替换成新模块

3.虚拟DOM一定比真实DOM快吗

不一定,需要分场景区分,下面是虚拟DOM比真实DOM快的一些场景:

  • 大量数据更新或者复杂视图变化

下面是虚拟DOM比真实DOM慢的一些场景:

  • 首次渲染时:真实DOM只需要解析HTML即可渲染,而虚拟DOM需要解析代码、生成虚拟DOM树、Diff算法、创建真实DOM
  • 极其简单的更新:例如只修改一个div的text

手写代码篇

1.手写数组扁平化flat

  • 场景:把[1,[2,[3]]]变成[1,2,3]
  • 附加要求:支持控制深度
javascript 复制代码
Array.prototype.myFlat = function(depth = 1) {
  let result = [];
  this.forEach(item => {
    if (Array.isArray(item) && depth > 0) {
      result = [ ...result, ...item.myFlat(depth - 1), ];
    }
    else {
      result.push(item);
    }
  })
  return result;
}

const arr = [1, 2, [3, 4, [5, 6]]];
console.log(arr.myFlat(1)); // [1, 2, 3, 4, [5, 6]]

2.手写Promise.retry(请求重试)

  • 场景:接口不稳定,如果失败了,自动重试3次,每次间隔1秒
javascript 复制代码
function retry(fn, times, delay) {
	return new Promise((resolve, reject) => {
		function attempt() {
			fn().then(resolve).catch(err => {
				console.log("还有" + (times - 1) + "次机会");
				if (times > 1) {
					times--;
					setTimeout(attempt, delay);
				}
				else {
					reject(err);
				}
			})
		}
		attempt();
	})
}

// 模拟一个可能失败的异步函数
function unstableAsyncFunction() {
	return new Promise((resolve, reject) => {
		const success = Math.random() > 0.5;
		setTimeout(() => {
			if (success) {
				resolve("成功了!");
			} else {
				reject("失败了!");
			}
		}, 500);
	});
}

// 使用 retry 函数
const f = retry(unstableAsyncFunction, 3, 1000)
	.then(result => {
		console.log("最终结果:", result);
	})
	.catch(error => {
		console.error("最终失败:", error);
	});	
相关推荐
cipher4 小时前
Web3全栈学习与实战项目
前端·后端·区块链
冴羽4 小时前
资深前端都在用的 9 个调试偏方
前端·javascript
SimonSkywalke4 小时前
鸟哥的Linux私房菜快速阅读笔记(一) 指令使用、常见指令、寻求帮助
后端·面试
左夕4 小时前
深入理解Vue中的插槽:概念、原理与应用
前端·vue.js
我叫蒙奇4 小时前
flex: 1 vs flex: auto 最通俗的解释
前端
兆子龙4 小时前
万字解析 OpenClaw 源码架构:从入门到精通
前端·javascript
@大迁世界4 小时前
精通 React 面试:从零到中高级
前端·javascript·react.js·面试·前端框架
野犬寒鸦4 小时前
SAP后端实习开发面试:操作系统与网络核心考点及Linux与Redis
java·服务器·网络·后端·面试
梁正雄5 小时前
Python前端-2-css基础
前端·python·html
Mr Xu_5 小时前
巧用多背景图层打造精美 CSS 背景 —— 基于 SVG 的视觉合成技巧
前端·css