二线城市前端面试-被侮辱了

220 阅读5分钟

之前我这边一直在北京,写的vue 不太多,大概最近一年在写,但具体的底层没仔细看,这几天选了二线城市先面面,看下自己缺少的部分,结果还真是打自己的脸

我这边找了一家郑州的公司,还可以,薪资12-18k,其他就不说了,说面试过程

进来先做自我介绍,这里我的自我介绍也一般,就是什么时候来的北京,第一家是什么,做了什么,用了什么技术,第二家,第三家,然后爱好,平时空闲都做什么,没了,很大众化,很一般。

做完自我介绍面试官开始问

第一个,说一下vue的数据劫持

因为自己写vue一年,知道这个数据劫持vue2和vue3 不一样,并且知道vue2.0的一些缺点,vue3.0用的是es6的proxy, 联想到数据劫持和数据双向绑定是有关联的,就直接把数据双向绑定和数据劫持放在一起说了,很简单,大概是这样

vue2.0

在 Vue 2 中,双向绑定是通过数据劫持结合发布-订阅模式实现的。

数据劫持(Observer):Vue 会遍历 data 对象的所有属性,并使用 Object.defineProperty 将这些属性转换为 getter 和 setter。这样,当访问或修改这些属性时,Vue 能够捕获到这些操作

依赖收集(Dep):在 getter 中,Vue 会进行依赖收集。每个属性都有一个 Dep 实例,用来存储所有依赖于该属性的 Watcher 实例。当属性被访问时,当前的 Watcher(如果有)会被添加到 Dep 中。

派发更新(Watcher):当属性被修改时,setter 会被触发,然后 Dep 会通知所有相关的 Watcher 实例。Watcher 实例收到通知后,会执行更新操作,比如更新视图。

编译模板(Compile):Vue 的编译器会解析模板,将模板中的指令(如 v-model)和插值表达式({{ }})转换为更新视图的函数,并创建对应的 Watcher。每个 Watcher 都会订阅相关数据的变化,当数据变化时,Watcher 会执行更新函数来更新视图。

双向绑定的关键(v-model):对于 v-model 指令,它实际上是语法糖。在输入框上使用 v-model,相当于同时绑定了 :value@input 事件。当输入框的值变化时,会触发 input 事件,从而更新数据;当数据变化时,通过数据劫持触发 setter,进而更新视图

vue 3.0

Vue 3 使用 ES6 的 Proxy 替代了 Object.defineProperty,带来了更好的性能和更完善的劫持能力。数据劫持:Vue 3 使用 Proxy 来创建一个对象的代理。Proxy 可以拦截对象的各种操作,包括属性访问、赋值、删除等,而不需要遍历对象的每个属性。

依赖收集与派发更新(Reflect 和 Effect):Vue 3 使用 Reflect 来操作对象,并在代理的 get 拦截器中收集依赖(track),在 set 拦截器中触发更新(trigger)。Vue 3 引入了 effect 函数(类似于 Vue 2 的 Watcher),用于执行副作用(如更新视图)。

响应式 API:Vue 3 提供了多个响应式 API,如 reactive(用于对象)、ref(用于基本类型)等。ref 内部也是通过 reactive 来实现的,对于基本类型,它使用了一个对象的 value 属性来包裹。

编译优化:Vue 3 在编译模板时进行了优化,生成的渲染函数能够更精确地更新 DOM,减少了不必要的比较。

双向绑定的实现:类似于 Vue 2,v-model 在 Vue 3 中也是语法糖,但做了一些改进,例如可以自定义 v-model 的参数(如 v-model:title)和多个 v-model 绑定。

回答的中间,面试官说,你不要一直盯着屏幕,他是担心我看着屏幕念,我没念,我说我需要看着摄像头,然后继续。说完上面之后,他这时候问,vue2.0, Object.defineProperty怎么监听的数组,出现了哪些问题,为什么用proxy 替代,这个我之前看了一些,但是怎么监听的数组,我确实不知道,只能临场想一想,我先说了下,Object.defineProperty无法监听到对象的新增和删除,数组元素的重新赋值和数组长度,怎么监听的数组,我说了一个数组也是对象的一种,和监听对象一样,这里是错误的,我理解他是想让我说vue2.0里面重新改写了数组的方法,那7个方法【push,pop,shift,unshift,reserve,splice,sort】,我没回答出来,然后接着问我,这些问题他们是怎么处理,监听不到对象的新增和删除,他们怎么解决的,我真不知道,这时候,我觉得我太菜了,我脑子转了一下,想到了vue.set 和 vue.delete, 说了一下,应该是通过他们来处理的,接着问,vue.set 和 vue.delete 怎么实现的,原理是什么,这我脑子没任何关于set,delete的知识,靠猜,也不一定对,我说我不知道,他接着问,数据双向绑定说一下,然后我刚说的就是双向绑定和数据劫持,他说怎么渲染的,v-model怎么到视图的,我想了一下,说了一个网上曾经看到的有点印象的,Vue 的双向绑定是通过数据劫持实现的,结合发布-订阅模式,在数据变化时自动更新视图,在用户输入时更新数据。v-model 是语法糖,简化了表单元素的双向绑定。数据变化到setter,再到Dep.notify,通过观察者发布订阅模式通知到watcher,watcher拿到数据,进行更新视图,接着问v-model 是怎么实现的,我上面有说过类似@input事件,v-model只是一个语法糖,这时候他觉得回答的很片面,变现出讥笑的面容,然后说,我没问题,接着退出会议,离开了。

离开了会议,我心情没有平静下来,想着郑州问的都这么深,还是我太菜了,我想得仔细看下底层,然后梳理一下。

整个过程就是这么一过程

image.png

后续我把答案整理好接着发出来