最近闲来无事,面试了一次,记录一下面试中出现的问题。
Vue响应式原理
- 任何一个Vue Component都有一个与之对应的
Watcher
实例。 - Vue
data
上的属性会使用Object.defineProperty
添加getter
和setter
。 - 当Vue Component
render
函数被执行的时候,data
会被触碰(touch)
,即被“读”,此时getter
方法会被触发,收集依赖。 data
被改动时(主要是用户操作),setter
方法会被调用,此时Vue会去通知(主要是通过getter
收集的依赖,调用Watcher
update)所有依赖于此data
的组件去更新。
上述只是数据改变视图的过程,是单向绑定,Vue怎么做到双向绑定
使用v-model
实现双向绑定,v-model
本质上是一个语法糖。下面两种写法作用基本相同。
1 | Vue({ |
v-model
主要是在组件上添加了value
属性,所以在我们使用v-model
的时候不能同时使用value
。除此之外v-model
也在运行时做了一些优化(例如中文输入触发input事件的处理,用到transitionstart
, transitionend
事件),可以支持表单原生组件,也可以支持自定义组件。
js的事件循环
- 所有同步任务在主线程上执行,形成一个执行栈。
- 主线程之外还有一个“任务队列”。只要异步任务有了结果,就在“任务队列”中放一个事件。
- 一旦执行栈中的任务执行完毕,系统会读取“任务队列”,看有哪些事件,将对应的异步任务结束等待状态,并放入执行栈开始执行。
- 不断重复上面三步。
“任务队列”又分为两个类型:macro task
、micro task
,每个macro task
结束后都要清空micro task
。
在浏览器环境下,常见的macro task
有setTimeout
、MessageChannel
、postMessage
;常见的micro task
有Promise.then
、MutationObserver
。
Vue nextTick实现
在使用Vue过程中,在改变数据之后获取DOM,要在nextTick
回调中才能获取改变之后的数据,是因为数据变化到DOM的变化是一个异步的过程。nextTick
将所有回调函数推到一个队列中,再在下一个事件循环中全部执行。优先使用micro task
实现。
mpvue为什么可以使用vue的语法写小程序
大概原理
- Vue.js实例与小程序Page实例建立关联
- 小程序和Vue.js生命周期建立映射关系,能在小程序生命周期中触发Vue.js生命周期
- 小程序事件建立代理机制,在事件代理函数中触发与之对应的Vue.js组件事件响应
- vue与小程序数据同步
…操作符
- rest参数
用户获取函数的多余参数,替代arguments
对象。
1 | function add(...values) { |
- 扩展运算符
扩展运算符的应用比较广泛,例如:
- 参数传递
arr.push(...[1,2,3])
- 合并数组
[...arr1, ...arr2, ...arr3]
- 字符串转数组
[...str]
,任何实现了Iterator
接口的对象都可以用扩展运算符转为真正的数组。
PromiseA+规范
一个Promise
代表一个异步操作的最终结果。主要的操作方式是调用then
方法,它接收的回调函数接收Promise
成功或失败的结果。
一个Promise
有且只有一个状态(pending、fulfilled、rejected)。
pending状态可以转变为fulfilled或rejected状态,反之则不行。
fulfilled状态必须有一个value且不可改变。
rejected状态必须有一个reason且不可改变。
一个Promise
必须提供一个then
方法,用来获取当前或最终的value或reason,一个Promise
的then
方法接收两个可选参数。then
方法返回一个新的Promise
对象,可链式调用。
使用try…catch能否捕获promise的异常,全局处理promise错误的方法
- 不可以,try…catch执行捕获同步代码的错误。
- 监听
unhandledrejection
事件,可以捕获未处理的Promise
错误。
1 | window.addEventListener('unhandledrejection', event => ...) |
给Promise添加一个finally方法
Promise
标准中仅指定了Promise
对象的then
方法的行为,其它一切常用的方法都没有指定。finally
可以用对then
函数的包装实现。
1 | Promise.prototype.finally = function(fn) { |
实现一个once函数,传入一个函数参数,只会执行一次
1 | function once(fn) { |
TCP协议如何做到保证数据的正确
- 确认和重传:接收方收到报文会确认,发送方一段时间没有收到确认就重传。
- 数据校验。
- 数据合理分片和排序。
- 流量控制:当接收方来不及处理发送的数据,提示发送方降低发送的频率,防止包丢失。
- 拥塞控制:当网络拥塞时,减少数据的发送。
TCP三次握手
- (SYN=1, seq=x):
客户端发送一个TCP的SYN标志位置1的包,指明客户端打算连接的服务器端口,以及初始序号X,保存在包头的序列号字段里,发送完毕后,客户端进入SYN_SEND
状态。 - (SYN=1,ACK=1,seq=y,ACKnum=x+1):
服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1.服务器选择自己ISN序列号,放到Seq域里,同时将确认序列号(Acknowledgement Number)设置为客户端的ISN+1,即X+1。发送完毕后,服务器端进入SYN_RCVD
状态。 - (ACK=1,ACKnum=y+1):
客户端再次发送确认包(ACK),SYN标志位为1,并且把服务器发来的ACK的序号字段+1,放在确认字段中发送给对方,并且在数据段放写的+1
发送完毕后,客户端进入ESTABLISHED
状态,当服务器接收到这个包时,也进入ESTABLISHED
状态,TCP握手结束。
https的握手
- 客户端向服务器端索要并验证公钥。
- 双方协商生成“对话密钥”。
- 双方采用“对话密钥”进行加密通信。
webpack xxx-[hash].js的作用,为什么使用?不行
文件改变hash会改变,更新缓存。
使用?v=xxx
,在使用CDN的过程中,涉及到html
和静态资源更新的时间差问题,在两种资源上线的间隔内可能会出现资源错误的情况。
CSS BFC是什么
块状格式化上下文(Block Formatting Context),是Web页面的可视化CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其它元素交互的区域。
块状格式化上下文对浮动定位与清楚浮动都很重要。浮动定位和清除浮动定位只会应用于一个BFC内的元素。浮动不会影响其它BFC元素中的布局,而清除浮动只能清除同一BFC中在它前面的元素浮动。外边剧折叠也只会发生在属于同一BFC块之间。
具有BFC特性的元素可以看作是隔离了的独立容器,容器里面的元素不会在布局上影响到外面的元素,并且BFC具有普通容易所没有的一些特性。
可以触发BFC特性:
- body根元素
- 浮动元素:float除none以外的值
- 绝对定位元素: position(absolute、fixed)
- display为inline-block,table-cells,flex
- overflow除了visible以外的值
BFC和浮动的关系
BFC可以包含浮动的元素。浮动元素会脱离文档流,使容器高度塌陷,如果触发容器的BFC,那么容器将会包裹浮动元素。
BFC可以阻止元素被其它浮动元素覆盖。
给定两个有序数据,实现一个merge
函数,将数据合并并且保证有序
1 | function merge(a1, a2) { |
或者…
1 | function merge(a1, a2) { |
webpack原理、如何实现异步chunk
webpack还不太熟… 日后再更