前端面试总结(持续更新中)

目录

一、vue2和vue3的区别

1.API的变化:

 Vue 3引入了组合式API(Composition API),使用函数而不是选项对象来组织组件的代码,提高了代码的可读性和可维护性。
 这与Vue 2的选项式API(Options API)相比,使得代码更加集中和易于管理。‌

2.数据绑定原理:

Vue 2使用ES5的Object.defineProperty实现数据绑定
而Vue 3使用ES6的Proxy对象进行数据代理,能够更有效地监听对象和数组的变化,提高了响应性。‌

3.生命周期钩子

Vue 3的生命周期钩子与Vue 2有所不同,例如Vue 3引入了setup函数作为生命周期的开始
而Vue 2的生命周期钩子如beforeCreate和created在Vue 3中不再直接使用,而是通过setup函数内部处理。

4.多根节点

Vue 3允许组件有多个根节点,这简化了组件的结构,使得布局更加灵活。相比之下
Vue 2要求每个组件只能有一个根节点。‌

5.性能优化:

Vue 3在性能优化方面有所提升,例如通过使用createStaticVNode方法生成静态节点,直接通过innerHTML渲染,避免了不必要的对象创建和渲染过程。‌

6.异步组件(Suspense)

Vue3 提供 Suspense 组件,允许程序在等待异步组件加载完成前渲染兜底的内容,如 loading ,使用户的体验更平滑。使用它,需在模板中声明,并包括两个命名插槽:default 和 fallback。Suspense 确保加载完异步内容时显示默认插槽,并将 fallback 插槽用作加载状态

7. Teleport

Vue3 提供 Teleport 组件可将部分 DOM 移动到 Vue app 之外的位置。比如项目中常见的 Dialog 弹窗。

8. TypeScript支持

Vue3 由 TypeScript 重写,相对于 Vue2 有更好的 TypeScript 支持。
Vue2 Options API 中 option 是个简单对象,而 TypeScript 是一种类型系统,面向对象的语法,不是特别匹配。
Vue2 需要vue-class-component强化vue原生组件,也需要vue-property-decorator增加更多结合Vue特性的装饰器,写法比较繁琐。

9.diff算法不同

vue2中的diff算法
遍历每一个虚拟节点,进行虚拟节点对比,并返回一个patch对象,用来存储两个节点不同的地方。用patch记录的消息去更新dom
缺点:比较每一个节点,而对于一些不参与更新的元素,进行比较是有点消耗性能的。特点:特别要提一下Vue的patch是即时的,并不是打包所有修改最后一起操作DOM,也就是在vue中边记录变更新。(React则是将更新放入队列后集中处理)。

vue3中的diff算
在初始化的时候会给每一个虚拟节点添加一个patchFlags,是一种优化的标识。只会比较patchFlags发生变化的节点,进行识图更新。而对于patchFlags没有变化的元素作静态标记,在渲染的时候直接复用。

10.更快的渲染性能:

Vue3 相比 Vue2 来说,Vue3 重写了虚拟 Dom 实现,编译模板的优化,更高效的组件初始化。

11.更小的体积:

Vue 3 的运行时核心相比 Vue 2 更小,这意味着更小的打包体积,减少了前端加载时间。
Tree-shaking 支持:Vue 3 代码更容易被 Tree-shaking 优化,因此可以更好地剔除不需要的代码。

二、vue3的使用你觉得有没有更好用,更好用在哪里?

1.性能提升:‌

Vue 3.0通过优化源码体积、‌重写虚拟DOM、‌升级响应式系统等方式,‌显著提升了性能。‌此外,‌通过tree-shaking和静态分析,‌Vue 3.0还减小了体积,‌移除了一些冷门API,‌进一步优化了打包过程

2.TypeScript支持:‌

Vue 3.0增强了对TypeScript的支持,‌提供了更好的类型推断和自动补全功能,‌这对于使用TypeScript进行开发的开发者来说是一个巨大的改进

3.新的API:‌

Vue 3.0引入了组合API(‌Composition API)‌,‌使得代码编写更加灵活和模块化。‌这种新的API设计使得代码组织更加清晰,‌便于维护和扩展

4.避免DOM元素不存在问题:‌

Vue 3.0中,‌使用setup函数代替了Vue 2中的beforeCreate和created,‌避免了在created中操作DOM元素可能出现的错误。‌此外,‌vue3的组合式api中的onUnmounted和unmounted分别代替了vue2中的beforeDestory和destoryed,‌进一步减少了操作DOM元素时可能出现的问题

5.使用proxy代替Object.defineProperty:‌

Vue 3.0使用proxy来实现响应式数据,‌相比Vue 2中使用的Object.defineProperty,‌proxy的效率更高,‌且能够直接监听对象及其属性的变化,‌而不需要初始化时遍历所有属性,‌大大提高了响应式系统的效率和灵活性

6.静态提升和预字符串化:‌

Vue 3.0通过静态提升和预字符串化等优化手段,‌进一步提高了渲染性能。‌静态节点只会被创建一次,‌而大量的静态内容会被直接编译为普通字符串节点,‌减少了不必要的渲染开销

7.自定义指令和watchEffect:‌

Vue 3.x改进了自定义指令API,‌使其更加灵活和强大,‌允许开发者封装可重用的DOM操作逻辑。‌同时,‌新增的watchEffect API可以自动追踪响应式依赖并执行副作用,‌简化了代码结构,‌减少了潜在的遗漏或错误

综上所述,‌Vue 3.0通过引入新的API、‌优化性能、‌增强TypeScript支持等方式,‌为开发者提供了更加高效、‌灵活的开发体验。‌

三、vue3diff算法判断不一样是本身就有的还是需要设置什么?

在Vue 3中,diff算法用于比较新旧虚拟节点,并识别需要应用于实际DOM的最小变化。如果Vue 3判断两个虚拟节点不同,这通常是因为它们自身就不一样,比如标签名、属性、子节点等发生了变化。

如果你想要Vue 3在比较虚拟节点时认为两个节点不同,不需要额外设置,这是Vue 3的默认行为。如果你需要改变这种默认行为(例如,实现自定义的diff算法或优化性能),你可能需要使用Vue 3的自定义渲染函数或者修改Vue的源码。

四、做登录态为何选择localStroge?为啥不用cookie

1.安全性:‌

在某些情况下,‌开发者可能认为将令牌存储在Cookie中存在安全风险,‌尤其是在面对跨站脚本攻击(‌XSS)‌时。‌使用localStorage可以减少某些安全风险,‌因为localStorage中的数据不会自动发送到服务器,‌且可以通过加密等安全措施来增强数据的安全性

2.存储容量:

cookie的大小通常限制在4KB左右,‌而localStorage的存储容量可达5MB,‌这使得localStorage更适合存储大量数据

3.跨域请求处理:‌

在前后端分离的架构中,‌如单页应用或移动应用,‌前端和后端通过API进行通信。‌在这种情况下,‌Cookie可能因为跨域请求的限制而不易管理,‌而localStorage提供了一种更方便的解决方案,‌允许前端应用程序直接访问和管理存储在本地的令牌

4.用户体验:‌

localStorage允许令牌在浏览器关闭后仍然保持有效,‌这意味着用户关闭浏览器后再次打开时仍保持登录状态,‌无需重新输入凭据,‌提供了更好的用户体验

综上所述,‌选择localStorage进行登录态管理是基于其对数据安全的增强、‌较大的存储容量、‌对跨域请求的更好处理,‌以及提升用户体验的考虑

五、localstorage和cookie有什么区别

1.数据大小

localStorage的存储空间通常较大,可以达到5MB甚至更多,而cookie的存储空间相对较小,通常限制在4KB左右。‌

2.有效期

localStorage中的数据可以一直保留在浏览器端,除非被明确删除,而cookie的有效期可以自行设置,也可以设置为一直有效。‌

3.是否随请求发送

cookie会在每次HTTP请求时自动发送给服务器,如果设置过多的cookie,可能会增加通信负荷。相比之下,localStorage不会自动发送给服务器,因此不会增加额外的通信负荷。‌

4.安全性

由于localStorage和sessionStorage不会在请求之间发送,因此不适合存储敏感信息。而cookie虽然可以通过HTTP请求发送,但其安全性较低。‌

六、接手一个新的做登录态的选择,你会选择什么存储?

对于登录态的项目,‌选择存储方案时,‌主要考虑的是数据的持久性、‌安全性、‌以及访问的便捷性。‌在这种情况下,‌localStorage是一个合适的选择。

七、浏览器跨标签页实现方式

1. 使用localStorage或sessionStorage存储共享数据,并通过监听storage事件来实现数据的变化检测和同步更新。

监听storage变化可以使用 window.addEventListener 来实现,操作简单,同域名下共享数据

2. 使用BroadcastChannel API,它提供了一种跨窗口通信的机制,可以在不同标签页之间发送消息。

3.使用window.postMessage()方法,该方法允许在不同的窗口或标签页之间安全地传递消息。通常,对于两个不同页面的脚本,只有同源时,这两个脚本才能相互通信。

4. 借助服务端的实时通信技术,如WebSocket,通过服务器作为中介来实现标签页之间的消息传递和数据同步。

5. Service worker,允许开发者拦截和控制页面发出的网络请求,以及管理缓存,从而实现离线访问、性能优化和推送通知等功能。

6. SharedWorker 是一种在 Web 浏览器中使用的 Web API,它允许不同的浏览上下文,如不同的浏览器标签页之间共享数据和执行代码。它可以用于在多个浏览上下文之间建立通信通道,以便它们可以共享信息和协同工作。

7. IndexedDB 是一种在浏览器中用于存储和管理大量结构化数据的 Web API。它提供了一种持久性存储解决方案,允许 Web 应用程序在客户端存储数据,以便在不同会话、页面加载或浏览器关闭之间保留数据。

8. cookie,直接使用 document.cookie 可以获取cookie值

八、虚拟滚动原理及实现方式

1.原理

主要在于优化长列表或大量数据的渲染性能,通过只渲染用户当前可见区域的数据,而不是一次性渲染整个列表或数据集,从而减少‌DOM的操作,提高页面的响应速度和流畅度。

2.实现原理

1.计算可视区域的高度‌
2.创建占位元素
3.监听滚动事件
4.动态渲染列表项
5.使用‌CSS的transform属性

九、vuex为何要用action和mutation

mutation可以直接修改state的状态
action提交的是mutation,action里面可以包含异步操作

为什么Vuex要通过mutations修改state,而不能直接修改

vuex是单向数据流,如果在组件中可以直接修改state数据就违背了vuex这个仓库了
还有就是,如果组件内可以修改state数据,那么如果是异步修改怎么办?所以有很多无法预测的问题,而且可以读一下原文链接:

vuex 不但是一种全局修改数据的工具,更重要的意义是在于把跨组件的交互,拆分为基于状态管理的处理。

使用如 vuex 本身就是希望基于这样一个数据结构的约定,使得项目代码更加直观和简单。每一个 state树对应整个项目的一个数据,每一个 mutation 执行完成后都可以更新到一个新的状态。这样 devtools 就可以打个 snapshot 存下来。可以尝试开着 devtool 调用一个异步的 action,可以清楚地看到它所调用的 mutation 是何时被记录下来的,并且可以立刻查看 mutation 对应的状态。

所以,通过commit 提交 mutation 的方式来修改 state 时,vue的调试工具能够记录每一次 state 的变化,这样方便调试。但是如果是直接修改state,则没有这个记录,那样做会使状态不受我们管控。如果是多个模块需要引用一个state的,然后每个人可能由不同的人开发,如果直接修改值,可能会造成数据的混乱,Mutation 也记录不到,到时候调试会有麻烦。但是通过 mutation 修改 state 这样设计,就有个统一的地方进行逻辑运算去修改。如果逻辑有变动,修改一个地方就可以了。

十、js原型的继承,js原型

1、js原型的继承

‌JavaScript中的原型继承‌是一种对象通过另一个对象继承属性和方法的机制。JavaScript是一种基于原型的语言,这意味着对象可以从其他对象继承属性,而不是通过类继承。原型继承允许一个对象使用另一个对象的属性和方法,从而实现代码的重用和扩展性。

原型继承的实现方式

1、‌原型链继承‌:通过将子类型的原型指向父类型的实例来实现继承。这种方式下,子类型可以直接访问父类型的属性和方法。
2、‌构造函数继承‌:通过在子类型构造函数内部调用父类型构造函数来实现继承。这种方式可以确保子类型能够访问到父类型的属性,但无法直接访问父类型的原型上的方法。
3、组合继承‌:结合了原型链和构造函数的优点,通过在子类型构造函数内部调用父类型构造函数,并同时将子类型的原型设置为父类型的一个实例来实现继承。
4、寄生组合继承‌:通过借用构造函数和原型链继承的混合方式来实现继承,避免了原型链多次引用的问题,同时确保了方法的可重用性。日方提供
5、‌ES6继承‌:利用ES6引入的class关键字和extends关键字来实现面向对象编程中的类继承,虽然底层仍然是基于原型的继承机制,但提供了更直观和易于理解的语法。

2、js的原型

‌在JavaScript中,原型(Prototype)是一个对象,通过原型可以实现对象的属性继承。‌

每个JavaScript对象都有一个内部属性[[Prototype]],这个属性指向该对象的原型对象。原型对象本身也是一个对象,它包含了某些公共的属性和方法,可以被该对象以及其他对象共享。通过原型,JavaScript实现了基于原型的继承机制,即一个对象可以直接访问它的原型上定义的属性和方法。这种机制允许我们在创建对象时共享属性和方法,而不是为每个对象都重新定义相同的属性和方法。

原型分为“隐式原型”和“显示原型”。隐式原型是通过对象的__proto__属性访问的,而显示原型则是通过函数的prototype属性访问的。每个函数都有一个prototype属性,当一个函数被用作构造函数来创建实例时,这个函数的prototype属性值会被作为原型赋值给所有对象实例。这意味着所有实例的原型引用的是函数的prototype属性,从而实现属性的继承。
此外,JavaScript中的原型链是一种机制,当访问对象的属性或方法时,如果对象自身没有找到,就会沿着原型链向上查找,直到找到属性或方法,或者到达原型链的顶端(即Object.prototype)。这种链式的结构称为原型链,它允许JavaScript对象之间共享属性和方法,实现了动态语言的灵活性和扩展性。

十一

function Foo() {
    getName = function () { alert (1); };
    return this;
}
Foo.getName = function () { alert (2);};
Foo.prototype.getName = function () { alert (3);};
var getName = function () { alert (4);};
function getName() { alert (5);}

//请写出以下输出结果:
Foo.getName(); // 2
getName(); //4
Foo().getName();  // 1
getName(); // 1
new Foo.getName(); // 2
new Foo().getName(); // 3
new new Foo().getName(); // 3

十二、css如何不显示滚动条

1.计算滚动条宽度并隐藏起来
2.使用三个容器包围起来,不需要计算滚动条的宽度
3.伪对象选择器::-webkit-scrollbar

十三、手写一个">",不用图标

border-top:1px solid #333;
border-right: 1px solid #333
transform: rotate(45deg);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值