记录下我遇到过的前端面试题 (一)
(一)简述Vue的双向绑定:
最近的项目基本都是基于Vue进行开发的,但是却对Vue的双向绑定原理理解的马马虎虎。被面试到这个问题的时候,我的回答是:基于Object.defineProperty()这个核心方法,并且通过这个方法的setter和getter对数据进行劫持监听和设置新值。当被问到能再详细点吗,就傻眼了(自由发挥。。。)。
鉴于此,虽然不求完全吃透,但是用了这么久,起码双向绑定的实现逻辑得能简述出来。
Vue数据双向绑定原理
采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。此时实现过程涉及3个非常重要的东东:Observer、Watcher、Compile。
Observer: 一个数据监听器,首先是通过递归方法遍历所有的属性值,并且使用Object.defineProperty( )来对值进行劫持绑定。
Watcher:一个订阅者,用于接收Observer发来的更新信息,并且执行相应的更新回调。
Compile:对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,以及绑定相应的更新函数
实现过程:
首先数据监听器Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者Watcher。Watcher连接Observer和Compile的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图。
(二)说说浏览器渲染过程:
当时碰到这个问题的时候也是挺懵逼的,因为不太清楚问的是哪个过程。那么这边就以页面生成的过程作为问题。我记得我当时的回答是:首页HTML生成好DOM树,然后CSS规则生成树,接着结合HTML树和CSS规则树布局。嗯嗯,渣渣的问答。
具体渲染过程:
1. 解析HTML生成DOM树。
2. 解析CSS生成CSSOM规则树。
3. 将DOM树与CSSOM规则树合并在一起生成渲染树。
4. 遍历渲染树开始布局,计算每个节点的位置大小信息。
5. 将渲染树每个节点绘制到屏幕。
注意的是:
1. 渲染过程会碰到渲染阻塞。也就是当浏览器遇到一个 script 标记时,DOM 构建将暂停,直至脚本完成执行,然后继续构建DOM。每次去执行JavaScript脚本都会严重地阻塞DOM树的构建,如果JavaScript脚本还操作了CSSOM,而正好这个CSSOM还没有下载和构建,浏览器甚至会延迟脚本执行和构建DOM,直至完成其CSSOM的下载和构建。
2. CSS 优先:引入顺序上,CSS 资源先于 JavaScript 资源; JS置后:我们通常把JS代码放到页面底部,且JavaScript 应尽量少影响 DOM 的构建。
(三)实现一个滚动型的无限加载数据组件:
当时回答的实现逻辑是有2种:
(1) 首先请求前2页的数据,然后给滚动条绑定一个滚动事件,监听滚动条滚动距离,当滚动条滚动到离底部还有一定的距离的时候马上请求下一页的数据。(记得解绑事件)
(2) 首先请求前2页的数据,然后添加一个定时器函数,每隔0.5s监听当前浏览器高度,当滚动条高度离底部还有一定的距离的时候马上请求下一页的数据。(记得清楚定时器)
如果还有其他更好的办法,麻烦指教下哈哈哈。
(四)CSS垂直居中方式:
面试的时候好像回答出了好几个,也没回答全部。不过当时是被面试人员像挤奶一样挤出来的,面试员就一句:还有吗?
那就重新整理下:
(1)文本居中用line-height;
(2)vertical-align属性;
(3)display:table (或者:+ vertical-align);
(4)display:fiex;
(5)position:absolute + margin;(有多种实现方式,可以具体查查)
(6)position:absolute(50%, 50%) + transform:translate(-50%,-50%); //实际原理和第5点很像
(7)padding和margin + 已知距离;
(更多..... )
(五)实现接口同步请求的方式:
当时只回答出了函数内回调(俗称地狱回调)、Promise、async(await)。 后来查了下,通过generator函数也可以。
(六)JS的数据类型和引用类型:
六大数据类型:Number、String、Boolean、Null、Object、undefind(我当时漏掉这个);
三大引用类型:Object、Array、Function;
(七) 什么是高阶函数
英文叫Higher-order function。JavaScript的函数其实都指向某个变量。既然变量可以指向函数,函数的参数能接收变量,那么一个函数就可以接收另一个函数作为参数,这种函数就称之为高阶函数。常用高阶函数有map/reduce/filter等等。
(八) Flex布局
Flex 是 Flexible Box 的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性。任何一个容器都可以指定为 Flex 布局。基本属性:flex-basis、flex-direction、flex-flow、flex-grow、flex-shrink、flex-wrap
后话:
简单粗略记录了一下,希望以后再次面试到这个问题,肚子有水还能再吹吹!(仅供参考,如有疑问错误请指出)