前端|每天5道面试题(6)

947 阅读7分钟

每天背5道,务必背熟记住,希望能对找工作的小前端有点帮助

1、SPA是什么,有什么优缺点

SPA( single-page application )仅在 Web 页面初始化时加载相应的 HTML、JavaScript 和 CSS。一旦页面加载完成,SPA 不会因为用户的操作而进行页面的重新加载或跳转;取而代之的是利用路由机制实现 HTML 内容的变换,UI 与用户的交互,避免页面的重新加载。

优点:

  • 用户体验好、快,内容的改变不需要重新加载整个页面,避免了不必要的跳转和重复渲染;
  • 基于上面一点,SPA 相对对服务器压力小;
  • 前后端职责分离,架构清晰,前端进行交互逻辑,后端负责数据处理;

缺点:

  • 初次加载耗时多:为实现单页 Web 应用功能及显示效果,需要在加载页面的时候将 JavaScript、CSS 统一加载,部分页面按需加载;
  • 前进后退路由管理:由于单页应用在一个页面中显示所有的内容,所以不能使用浏览器的前进后退功能,所有的页面切换需要自己建立堆栈管理;
  • SEO 难度较大:由于所有的内容都在一个页面中动态替换显示,所以在 SEO 上其有着天然的弱势。

2、谈谈对MVVM的理解

MVVM 是Model-View-ModelView的缩写,是一种脱胎于 MVC 模式的设计模式
Model 代表数据层,负责存放业务相关的数据;
View 代表视图层,负责在页面上展示数据;
**ViewModel 是的作用是同步 View 和 Model 之间的关联。**数据会绑定到viewModel层并自动将数据渲染到页面中,视图变化的时候会通知viewModel层更新数据。

回答以上部分面试一般够用了,下面是扩展阅读:

viewModel 是由前端开发人员组织生成和维护的视图数据层。在这一层,前端开发者对从后端获取的 Model 数据进行转换处理,做二次封装,以生成符合 View 层使用预期的视图数据模型。需要注意的是 ViewModel 所封装出来的数据模型包括视图的状态和行为两部分,而 Model 层的数据模型是只包含状态的,比如页面的这一块展示什么,而页面加载进来时发生什么,点击这一块发生什么,这一块滚动时发生什么这些都属于视图行为(交互),视图状态和行为都封装在了 ViewModel 里。这样的封装使得 ViewModel 可以完整地去描述 View 层。

MVVM 框架实现了双向绑定,这样 ViewModel 的内容会实时展现在 View 层,前端开发者再也不必低效又麻烦地通过操纵 DOM 去更新视图,MVVM 框架已经把最脏最累的一块做好了,我们只需要处理和维护 ViewModel,视图就会自动得到相应更新。这样 View 层展现的不是 Model 层的数据,而是 ViewModel处理后 的数据,由 ViewModel 负责与 Model 层交互,这就完全解耦了 View 层和 Model 层,这个解耦是至关重要的,它是前后端分离方案实施的重要一环。

3、Vue2.x双向绑定原理和Vue3.x双向绑定原理

Vue2.x双向绑定原理

Vue 采用数据劫持+订阅发布模式实现双向绑定。通过 Object.defineProperty()方法来为组件中 data 的每个属性添加 get 和 set 方法,在数据变动时,触发 set 里相应的监听回调函数,将变动信息发布给订阅者。

回答以上即可,以下为详细解读:

这些 getter/setter 对用户来说是不可见的,但是在内部它们让 Vue 能够追踪依赖,在 property 被访问和修改时通知变更。

每个组件实例都对应一个 watcher 实例,它会在组件渲染的过程中把“接触”过的数据 property 记录为依赖。之后当依赖项的 setter 触发时,会通知 watcher,从而使它关联的组件重新渲染。

Vue3.x双向绑定原理

Vue3.x改用Proxy替代Object.defineProperty。因为Proxy可以直接监听对象和数组的变化,并且有多达13种拦截方法。并且作为新标准将受到浏览器厂商重点持续的性能优化。

Vue3.x是通过proxy(代理)实现的数据的双向绑定

区别:

  • Object.defineProperty一次性只能给对象的一个属性添加get&set方法,因此无法监听对象属性的变化,无法监听数组length的变化,只能通过一些数组方法变现实现。
  • Proxy:一次性给对象所有属性都设置get&set方法,可以监听对象属性变化和数组length变化

4、虚拟 DOM

虚拟DOM是将状态映射成视图的众多解决方案中的一种,是通过状态生成一个虚拟节点树,然后使用虚拟节点树进行渲染生成真实DOM,在渲染之前,会使用新生成的虚拟节点树和上一次虚拟节点树进行对比,只渲染不同的部分。

简单理解就是: 虚拟DOM就是js对象,该js对象模拟真实DOM的结构,有tagprops,chidren等属性分别保存了节点的名称,属性,子节点等。

为什么要使用虚拟DOM?

虚拟 DOM 就是为了解决浏览器性能问题而被设计出来的,前面所说的大量操作真实DOM会消耗浏览器的性能,是因为每次的DOM变化都会重新渲染页面,而虚拟DOM不会立即操作DOM,而是通过diff算法,把这些变化,保存到一个js对象中,最终将这个js对象,一次性attch 到 DOM 树上,再进行后续操作,避免大量无谓的计算量。即:把页面的更新全部保存到js对象中,等更新完成再一次性渲染成真实的DOM,最终交给浏览器绘制

虚拟dom的好处

  • 减少dom操作次数,虚拟dom将需要创建的元素存放在数组中,之后再一次性的插入到节点,同时借助dom diff 一层层比较dom变化来得到patch再更新dom;
  • 跨平台支持

vue中的虚拟DOM

在vue.js中,虚拟dom是用VNode这个class去定义和初始化虚拟dom的属性和方法。

5、Vue的生命周期

  • beforeCreate(创建前) 在数据观测和初始化事件还未开始

  • created(创建后) 完成数据观测,属性和方法的运算,初始化事件,$el属性还没有显示出来

  • beforeMount(载入前) 在挂载开始之前被调用,相关的render函数首次被调用。实例已完成以下的配置:编译模板,把data里面的数据和模板生成html。注意此时还没有挂载html到页面上。

  • mounted(载入后) 在el 被新创建的 vm.$el 替换,并挂载到实例上去之后调用。实例已完成以下的配置:用上面编译好的html内容替换el属性指向的DOM对象。完成模板中的html渲染到html页面中。此过程中进行ajax交互。

  • beforeUpdate(更新前) 在数据更新之前调用,发生在虚拟DOM重新渲染和打补丁之前。可以在该钩子中进一步地更改状态,不会触发附加的重渲染过程。

  • updated(更新后) 在由于数据更改导致的虚拟DOM重新渲染和打补丁之后调用。调用时,组件DOM已经更新,所以可以执行依赖于DOM的操作。然而在大多数情况下,应该避免在此期间更改状态,因为这可能会导致更新无限循环。该钩子在服务器端渲染期间不被调用。

  • beforeDestroy(销毁前) 在实例销毁之前调用。实例仍然完全可用。

  • destroyed(销毁后) 在实例销毁之后调用。调用后,所有的事件监听器会被移除,所有的子实例也会被销毁。该钩子在服务器端渲染期间不被调用。 官方图解:

本着能为找工作中的前端帮一点小忙的初衷,借鉴了掘金里面很多大佬的文章,如有侵权请告知