电话面,不定时忽然打过去问当初是否不便面试。
次要考察点:我的项目的具体实现,我的项目中遇到的难点,框架底层原理的意识。感觉问的比个别面试难,很重视细节和深度
一. 问简历上某个我的项目的具体实现,有没有遇到什么难点
二. 有哪个我的项目是你独立负责的,负责的我的项目从构建,部署,打包,框架选型是如何思考的
三. react 和 vue 的比拟,我的项目开发中怎么确定用哪个
1. 相似之处
- 都是用于创立 UI 的 JavaScript 库;
- 都疾速轻便(专一于发明前端的富利用。不同于晚期的 JavaScript 框架“功能齐全”,)
- 都有基于组件的架构;
- 都是用虚构 DOM;
- 都可放入单个 HTML 文件中,或者成为更简单 webpack 设置中的模块;
- 都有独立但罕用的路由器和状态治理库(Reat 与 Vue 只有框架的骨架,其余的性能如路由、状态治理等是框架拆散的组件。)
它们之间的最大区别是 Vue 通常应用 HTML 模板文件,而 React 则齐全是 JavaScript。Vue 有双向绑定语法糖。
2.区别:
-
监听数据变动的实现原理不同
Vue 通过 getter/setter 以及一些函数的劫持,能准确晓得数据变动。
React 默认是通过比拟援用的形式(diff)进行的,如果不优化可能导致大量不必要的 VDOM 的从新渲染。为什么 React 不准确监听数据变动呢?这是因为 Vue 和 React 设计理念上的区别,Vue 应用的是可变数据,而 React 更强调数据的不可变,两者没有好坏之分,Vue 更加简略,而 React 构建大型利用的时候更加鲁棒。
-
数据流不同
Vue1.0 中能够实现两种双向绑定:父子组件之间,props 能够双向绑定;组件与 DOM 之间能够通过 v -model 双向绑定。Vue2.x 中去掉了第一种,也就是父子组件之间不能双向绑定了(然而提供了一个语法糖主动帮你通过事件的形式批改),并且 Vue2.x 曾经不激励组件对本人的 props 进行任何批改了。
React 始终不反对双向绑定,提倡单向数据流,称为 onChange/setState()模式。
-
模板渲染形式不同
在表层上,模板的语法不同,React 通过 JSX 渲染模板。Vue 通过一种拓展的 HTML 语法进行渲染,但其实这只是表面现象,毕竟 React 并不必须依赖 JSX。
在深层上,模板的原理不同,这才是他们的本质区别:React 是在组件 JS 代码中,通过原生 JS 实现模板中的常见语法,比方插值,条件,循环等,都是通过 JS 语法实现的,更加纯正更加原生。而 Vue 是在和组件 JS 代码拆散的独自的模板中,通过指令来实现的,比方条件语句就须要 v-if 来实现对这一点,这样的做法显得有些独特,会把 HTML 弄得很乱。
-
框架实质不同
Vue 实质是 MVVM 框架,由 MVC 倒退而来;
React 是前端组件化框架,由后端组件化发展而来。
3. 各自的长处
React
- 通过模块化的构造使其领有灵便的代码,节省时间和老本。
- 助力简单应用程序的高性能的实现。
- 应用 React 前端开发可能更容易去做代码保护。
- 反对实用于 Android 和 iOS 平台的挪动端原生应用程序。
Vue
- 它的体积玲珑,便于装置和下载。
- 假使咱们正确利用,咱们就能够在多处重用 Vue。
- Vue.js 容许咱们更新网页中的元素,而无需渲染整个 DOM,因为它是虚构的 DOM。
- 须要较少的优化。
- 减速 Web 应用程序的开发,并容许大佬将模板到虚构 DOM 与编译器离开。
- 通过验证的兼容性和灵活性。
- 不论应用程序的规模如何,代码库都不会变。
4. 技术选型
这里联合本人理论工作中的领会来讲会更好,找了个大佬的参考 https://www.cnblogs.com/pengf…
四. 讲一下 React Diffing 算法
传统 diff 算法的问题
传统的 diff 算法是应用循环递归对节点进行顺次比照,复杂度为 O(n^3), 效率低下。
为了优化 diff 算法,React 提出了两个假如:
- 两个不同类型的元素会产生出不同的树
- 开发者能够通过
key
prop 来暗示哪些子元素在不同的渲染下能保持稳定
React diff 算法策略
- 针对树结构(tree diff):对 UI 层的 DOM 节点跨层级的挪动操作进行疏忽。(因为这种操作的数量很少)
- 针对组件构造 (component diff):领有雷同 类的两个组件生成类似的树形构造,领有不同 类的两个组件会生成不同的属性构造。
- 针对元素构造 (element-diff): 对于同一层级的一组节点,它们能够用 唯一性 的 id 辨别 (key 属性)
diff 具体优化
1.tree diff(树形构造)
- React 通过应用 updateDepth 对 虚构 DOM 树进行档次遍历
- 两棵树只对同一层级节点进行比拟,只有该节点不存在了,那么该节点与其所有子节点会被 齐全删除, 不在进行进一步比拟。
- 只须要遍历一次,便实现对整个 DOM 树的比拟。
如果产生跨级操作,React 不能复用已有节点,可能会导致 React 进行大量从新创立操作,这会影响性能。所以 React 官网举荐尽量避免跨层级的操作。
2.component diff
- 同类型组件,首先应用
shouldComponentUpdate()
办法判断是否须要进行比拟,如果返回true
,持续依照 React diff 策略比拟组件的虚构 DOM 树,否则不须要比拟 - 不同类型的组件,则将该组件判断为 dirty component,替换整个组件及其下的所有子节点
3.element diff
对于处于同一层级的节点,React diff 提供了三种节点操作
- 插入:新的组件不在原来的汇合中,是全新的节点,对汇合进行插入操作。
- 删除:组件曾经在汇合中,但汇合曾经更新,此时节点就须要删除。
- 挪动:组件并没有产生更新,只是地位产生扭转,例如:(A,B,C,D) → (A,D,B,C), 传统 diff 会在检测到旧汇合中第二位为 B,新汇合第二位为 D 时删除 B,插入 D,前面的所有节点都要从新加载,React diff 则是通过向同一层的节点增加 惟一 key 进行辨别,并且挪动。
补充:key 的作用
key 的作用次要是用来缩小没必要的 diff 算法比照,因为对于一个组件或者节点来说,只有父节点状态或者属性发生变化,该组件就会进行 diff 比照,即便该组件没变动,而如果为组件引入了 key 值,就能够在 diff 比照前先做一个校验,判断该组件是否须要 diff 比照,即便是 diff 比照,也能够判断该组件是间接更新操作还是销毁或者新建操作,从而进步了 diff 算法的效率;
特地在渲染同级同构造的组件们时,key 能够为它们加上了身份的标记,在 rerender 时,能够通过 key 来判断该组件是否曾经存在,是否须要跟新或者销毁,新建等操作,进步了 diff 算法在同级节点上的操
五. 讲一下 react 的生命周期
挂载阶段
组件的初始化阶段,将咱们的组件插入到 DOM 中,只会产生一次
- constructor
-
getDerivedStateFromProps
取代之前的 componentWillMount、componentWillReceiveProps 和 componentWillUpdate
componentWillMount- render
- componentDidMount
更新阶段
当组件的 props 扭转了,或组件外部调用了 setState 或者 forceUpdate 产生,会产生屡次
componentWillReceiveProps/UNSAFE_componentWillReceiveProps- getDerivedStateFromProps
-
shouldComponentUpdate
当组件接管到新属性,或者组件的状态产生扭转时触发。组件首次渲染时并不会触发。个别咱们通过该函数来优化性能:<u> 一个 React 我的项目须要更新一个小组件时,很可能须要父组件更新本人的状态。而一个父组件的从新更新会造成它旗下所有的子组件从新执行 render()办法,造成新的虚构 DOM,再用 diff 算法对新旧虚构 DOM 进行构造和属性的比拟,决定组件是否须要从新渲染 </u>
无疑这样的操作会造成很多的性能节约,所以咱们开发者能够依据我的项目的业务逻辑,在 shouldComponentUpdate()中退出条件判断,从而优化性能(手动判断组件是否须要更新)
例如 React 中的就提供了一个 PureComponent 的类,当咱们的组件继承于它时,组件更新时就会默认先比拟新旧属性和状态,从而决定组件是否更新。值得注意的是,PureComponent 进行的是浅比拟,所以组件状态或属性扭转时,都须要返回一个新的对象或数组
componentWillUpdate/UNSAFE_componentWillUpdate- render
-
getSnapshotBeforeUpdate
这个办法在 render 之后,componentDidUpdate 之前调用。有两个参数 prevProps 和 prevState,示意之前的属性和之前的 state,这个函数有一个返回值,会作为第三个参数传给 componentDidUpdate
代替 componentWillUpdate
-
componentDidUpdate
组件被更新实现后触发。页面中产生了新的 DOM 的元素,能够进行 DOM 操作
卸载阶段
- componentWillUnmount
componentWillUnmount
当咱们的组件被卸载或者销毁了就会调用,咱们能够在这个函数里去革除一些定时器,勾销网络申请,清理有效的 DOM 元素等垃圾清理工作
留神不要在这个函数里去调用 setState,因为组件不会从新渲染了
六.react 具体如何通过 shouldComponentUpdate 来缩小反复渲染,函数组件中怎么做
组件 state 或 props 被更新时能够通过这个生命周期判断是否持续渲染。
它承受两个参数nextProps
、nextState
,返回一个布尔值。
若不在代码中申明该生命周期,react 默认的解决是:
shouldComponentUpdate(nextProps, nextState) {return true;}
编写代码的时候能够通过该生命周期来优化渲染
shouldComponentUpdate(nextProps, nextState) {if (this.props.name === nextProps.name) {return false;}
return true;
}
应用 shouldComponentUpdate()以让 React 晓得以后状态或属性的扭转是否不影响组件的输入,默认返回 ture,返回 false 时不会重写 render,而且该办法并不会在初始化渲染或当应用 forceUpdate()时被调用,咱们要做的只是这样:
shouldComponentUpdate(nextProps, nextState) {return nextState.someData !== this.state.someData}
然而,state 里的数据这么多,还有对象,还有简单类型数据 React.PureComponent 解决这个问题
React.PureComponent
React.PureComponent 与 React.Component 简直完全相同,但 React.PureComponent 通过 props 和 state 的浅比照来实现 shouldComponentUpate()。如果对象蕴含简单的数据结构,它可能会因深层的数据不统一而产生谬误的否定判断(体现为对象深层的数据已扭转视图却没有更新)
函数组件用的是 useMemo
七. 讲一下 vue 的双向绑定,3.0 proxy 相比 2.0 的长处
八. 事件监听相干
事件代理应该留神什么
怎么设置在事件捕捉阶段去执行相应的函数
事件绑定 addventlisner 具体参数内容
九. 比拟两个对象是否相等 (不肯定是对象),JSON.stringify() 毛病
讲了两种,一种相似于深拷贝,递归遍历去比拟
第二种用 JSON.stringfy()转为 JSON 字符串去比拟,问这种办法的毛病是什么
十. 讲一下如何实现一个不定宽 div 的垂直居中
- flex
- position 定位,设本人的 position 为 absolute, 父元素为 relative,left: 50%,top:50% transform:translateX(-50%) translateY(-50%);
十一. get 和 post 的区别
参考
Vue 与 React 两个框架的区别和劣势比照 https://segmentfault.com/a/11…
react 中 key 的作用 https://segmentfault.com/a/11…