ZOOM面经答案

973 阅读10分钟

个人介绍,项目经历

1、Vue双向绑定

可以用 v-model 指令在表单元素上创建双向数据绑定

  1. 它会根据控件类型自动选取正确的方法来更新元素
  2. 它负责监听用户的输入事件以更新数据
  3. v-model总是将 Vue 实例的数据作为数据来源,因此我们应该通过 JavaScript 在组件的data选项中声明初始值

实现原理:v-model只不过是一个语法糖而已,真正的实现靠的还是

  1. v-bind:绑定响应式数据
  2. 触发oninput 事件并传递数据

2、Object.definePropety和Proxy区别

在 Vue2.x 的版本中,双向绑定是基于 Object.defineProperty 方式实现的。而 Vue3.x 版本中,使用了 ES6 中的 Proxy 代理的方式实现。

Object.defineProperty(obj, prop, descriptor)

使用 Object.defineProperty 会产生三个主要的问题:

  • 不能监听数组的变化

在 Vue2.x 中解决数组监听的方法是将能够改变原数组的方法进行重写实现(比如:push、 pop、shift、unshift、splice、sort、reverse),举例:

1// 我们重写 push 方法
2const originalPush = Array.prototype.push
3
4Array.prototype.push = function() {
5  // 我们在这个位置就可以进行 数据劫持 了
6  console.log('数组被改变了')
7
8  originalPush.apply(this, arguments)
9}
  • 必须遍历对象的每个属性

可以通过 Object.keys() 来实现

  • 必须深层遍历嵌套的对象

通过递归深层遍历嵌套对象,然后通过 Object.keys() 来实现对每个属性的劫持

Proxy

  • Proxy 针对的整个对象,Object.defineProperty 针对单个属性,这就解决了需要对对象进行深度递归实现对每个属性劫持的问题
  • Proxy 解决了 Object.defineProperty 无法劫持数组的问题

3、v-if和v-show区别

vue 中 v-show 与 v-if 的作用效果是相同的,都能控制元素在页面是否显示

  • 当表达式为true的时候,都会占据页面的位置
  • 当表达式都为false时,都不会占据页面位置

控制手段:v-show隐藏则是为该元素添加css--display:nonedom元素依旧还在。v-if显示隐藏是将dom元素整个添加或删除

编译过程:v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换

  • v-show 由false变为true的时候不会触发组件的生命周期
  • v-iffalse变为true的时候,触发组件的beforeCreatecreatebeforeMountmounted钩子,由true变为false的时候触发组件的beforeDestorydestoryed方法

4、HTTPS和HTTP区别

HTTPS是在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密(在传输层)
HTTP + 加密 + 认证 + 完整性保护 = HTTPS

  1. HTTPS协议需要到CA申请证书或自制证书

  2. HTTP的信息是明文传输; HTTPS则是具有安全性的ssl加密

  3. HTTP是直接与TCP进行数据传输; 而HTTPS运行在SSL/TLS(安全传输层协议)之上,SSL/TLS运行在TCP之上,用的端口也不一样,前者是80(需要国内备案),后者是443

  4. HTTP的连接很简单,是无状态的; HTTPS协议是由SSL+HTTP协议构建的,可进行加密传输、身份认证的网络协议,比HTTP协议安全

5、三次握手

TCP是面向连接的,三次握手就是用来建立连接的,四次握手就是用来断开连接的。 我们来看一下三次握手的过程:

  • 1、客户端主动发出请求,SYN标志位为1,表示要建立TCP连接,同时seq=x,表示告诉服务器我的数据会从x的序列号开始往后面发。

  • 2、服务端确认请求,SYN标志位为1,表示建立TCP连接,ACK=1表示收到了连接请求并确认,同时seq=y,表示告诉客户端我的数据会从y的序列号开始往后面发,ack=x+1,即告诉客户端你发的数据我收到了,你下一次发送的序列号应该是x+1。

  • 3、客户端确认回复,ACK=1表示收到了连接请求并确认,同时seq=x+1,表示之前的序列号+ 1,ack=y+1,即告诉服务端你发的数据我收到了,你下一次发送的序列号应该是y+1。

6、cache-control

7、localStorage和sessionStorage

共同点:统称webStorage 都是实现本地存储机制,保存在浏览器端、且同源的 都有四个API:setItem(存储)、getItem(读取)、removeItem(清除)、clear(清空)

区别:

  1. cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,而sessionStorage和localStorage不会自动把数据发送给服务器,仅在本地保存。cookie数据还有路径(path)的概念,可以限制cookie只属于某个路径下
  2. 存储大小限制也不同,cookie数据不能超过4K,同时因为每次http请求都会携带cookie、所以cookie只适合保存很小的数据,如会话标识。sessionStorage和localStorage虽然也有存储大小的限制,但比cookie大得多,可以达到5M或更大
  3. 数据有效期不同,sessionStorage:仅在当前浏览器窗口关闭之前有效;localStorage:始终有效,窗口或浏览器关闭也一直保存,因此用作持久数据;cookie:只在设置的cookie过期时间之前有效,即使窗口关闭或浏览器关闭
  4. 作用域不同,sessionStorage不在不同的浏览器窗口中共享,即使是同一个页面;localstorage在所有同源窗口中都是共享的;cookie也是在所有同源窗口中都是共享的

8、vue组件通信

  • 父子关系的组件数据传递选择 props  与 $emit进行传递,也可选择ref
    • 适用场景:父组件传递数据给子组件
    • 子组件设置props属性,定义接收父组件传递过来的参数
    • 父组件在使用子组件标签中通过字面量来传递值
  • 兄弟关系的组件数据传递可选择$bus,其次可以选择$parent进行传递
    • 使用场景:兄弟组件传值
    • 创建一个中央时间总线EventBus
    • 兄弟组件通过$emit触发自定义事件,$emit第二个参数为传递的数值
    • 另一个兄弟组件通过$on监听自定义事件
  • 祖先与后代组件数据传递可选择attrslisteners或者 Provide与 Inject
    • 在祖先组件定义provide属性,返回传递的值
    • 在后代组件通过inject接收组件传递过来的值
  • 复杂关系的组件数据传递可以通过vuex存放共享的变量

13、vue生命周期

Vue实例从创建到销毁的过程就是生命周期,即指从创建、初始化数据、编译模板、挂载Dom→渲染、更新→渲染、卸载等一系列过程 ue生命周期总共可以分为8个阶段:创建前后, 载入前后,更新前后,销毁前销毁后,以及一些特殊场景的生命周期

生命周期描述
beforeCreate组件实例被创建之初
created组件实例已经完全创建
beforeMount组件挂载之前
mounted组件挂载到实例上去之后
beforeUpdate组件数据发生变化,更新之前
updated数据数据更新之后
beforeDestroy组件实例销毁之前
destroyed组件实例销毁之后
activatedkeep-alive 缓存的组件激活时
deactivatedkeep-alive 缓存的组件停用时调用
errorCaptured捕获一个来自子孙组件的错误时被调用
生命周期描述
-------------------------------------------
beforeCreate执行时组件实例还未创建,通常用于插件开发中执行一些初始化任务
created组件初始化完毕,各种数据可以使用,常用于异步数据获取
beforeMount未执行渲染、更新,dom未创建
mounted初始化结束,dom已创建,可用于获取访问数据和dom元素
beforeUpdate更新前,可用于获取更新前各种状态
updated更新后,所有状态已是最新
beforeDestroy销毁前,可用于一些定时器或订阅的取消
destroyed组件已销毁,作用同上

9、怎么判断数据类型

  • 使用typeof进行判断

    语法:typeof 判断的数据
    特点:可以准确判断基本数据类型,无法对复杂数据类型进行准确判断

  • 使用constructor进行判断

    语法:对象名.constructor
    特点:只能判断复杂数据类型,不能判断基本数据类型

  • 使用instanceof进行判断

    语法:对象名 instanceof 构造函数
    特点:只能判断复杂数据类型,不能判断基本数据类型

  • 使用Object.prototype.toString.call()判断

    语法:Object.prototype.toString.call(需要判断的数据)
    特点:可以准确判断所有数据类型

10、组件化编码流程

1、按照功能点拆分静态组件 2、实现动态组件,考虑数据的存放位置,一个组件在用就放在组件身上,如果是多个组件共同使用,就放在他们的父组件身上(状态提升)。 3、实现交互:从绑定事件开始

11、flex属性

容器属性有:

  • flex-direction:决定主轴的方向(即项目的排列方向)
  • flex-wrap:决定容器内项目是否可换行
  • flex-flow:默认值为row nowrap水平不换行
  • justify-content:定义了项目在主轴上的对齐方式
  • align-items:定义项目在交叉轴上如何对齐
  • align-content:定义了多根轴线的对齐方式。

flex属性是flex-growflex-shrink 和 flex-basis的简写

  • flex: 1 相当于flex-grow:1,父元素设置display:flex属性,固定侧边栏,子元素设置flex:1会自动填充剩余空间

12、js的事件循环机制

为了解决js单线程运行阻塞问题,引入事件循环的运行机制。同步任务进入主线程,异步任务进入任务队列,主线程内的任务执行完毕为空,会去任务队列读取对应的任务,推入主线程执行,上述过程的不断重复就是事件循环。

13、不能使用箭头函数的情况

1.不应该使用箭头函数来定义一个生命周期方法

2.不应该使用箭头函数来定义method函数

3.不应该使用箭头函数来定义计算属性函数

4.不应该对 data 属性使用箭头函数

5.不应该使用箭头函数来定义 watcher 函数

原因: 箭头函数绑定了父级作用域的上下文,this 将不会按照期望指向 Vue 实例。不能使用this来访问你组件中的data数据以及method方法了。this将会指向undefined。

14、虚拟DOM

创建虚拟DOM就是为了更好将虚拟的节点渲染到页面视图中,所以虚拟DOM对象的节点与真实DOM的属性一一照应,虚拟 DOM 最大的优势在于抽象了原本的渲染过程,实现了跨平台的能力。

15、深拷贝和浅拷贝

浅拷贝是创建新的数据,这个数据有着原始数据属性值的一份精确拷贝。如果属性是基本类型,拷贝的就是基本类型的值。如果属性是引用类型,拷贝的就是内存地址。

深拷贝是开辟一个新的栈,两个对象属完成相同,但是对应两个不同的地址,修改一个对象的属性,不会改变另一个对象的属性。

常见的深拷贝方式有:

  • _.cloneDeep()
  • jQuery.extend()
  • JSON.stringify()
  • 手写循环递归