1、讲一下盒模型,普通盒模型和怪异盒模型有什么区别?
标准的盒子模型的大小是:content(区域内容大小)+padding(内边距)+border(边框)+margin(外边距);
注:标准盒子的初始设置宽高大小不包含padding、border和margin的大小。
怪异的盒子模型的大小是:content(区域内容大小)+margin(外边距);
注:怪异盒子的初始设置宽高大小包含padding、border大小在内,但不包含margin的大小。
2、CSS如何实现垂直居中?
1、通过vertical-align:middle实现CSS垂直居中。
2、通过display:flex实现CSS垂直居中。
3、通过伪元素:before实现CSS垂直居中。
4、通过display:table-cell实现CSS垂直居中。
5、通过隐藏节点实现CSS垂直居中。
6、已知父元素高度通过transform实现CSS垂直居中。
7、到垂直居中的位置。
8、通过line-height实现CSS垂直居中。
3、伪类和伪元素的区别是什么?
伪类和伪元素的根本区别在于:
它们是否创造了新的元素(抽象)。从我们模仿其意义的角度来看,如果需要添加新元素加以标识的,就是伪元素,反之,如果只需要在既有元素上添加类别的,就是伪类。
伪类的例子有:
:hover
:active
:first-child
:visited
等。
伪元素的例子有:
:first-line
:first-letter
:after
:before
4、call bind apply的区别?(场景:两个arr合并)(箭头函数是否变化)(判断是否array)
1.apply 、 call 、bind 三者都是用来改变函数的this对象的指向的;
2.apply 、 call 、bind 三者第一个参数都是this要指向的对象,也就是想指定的上下文;
3.apply 、 call 、bind 三者都可以利用后续参数传参;
bind是返回对应函数,便于稍后调用;apply、call则是立即调用 。
区别:
call和apply的功能相同,区别在于传参的方式不一样
bind 和call/apply 有一个很重要的区别,一个函数被 call/apply 的时候,会直接调用,但是bind 会创建一个新函数。当这个新函数被调用时,bind() 的第一个参数将作为它运行时的 this,之后的一序列参数将会在传递的实参前传入作为它的参数
5、防抖节流的概念?实现防抖和节流(场景:连续点击)
防抖
防抖具体指的是某个函数在某段时间内,无论触发了多少次回调,都只执行最后一次。假如我们设置了一个等待时间 3 秒的函数,在这 3 秒内如果遇到函数调用请求就重新计时 3 秒,直至新的 3 秒内没有函数调用请求,此时执行函数,不然就以此类推重新计时
节流:
函数节流指的是某个函数在一定时间间隔内(例如 3 秒)只执行一次,在这 3 秒内 无视后来产生的函数调用请求,也不会延长时间间隔。3 秒间隔结束后第一次遇到新的函数调用会触发执行,然后在这新的 3 秒内依旧无视后来产生的函数调用请求,以此类推。函数节流非常适用于函数被频繁调用的场景,例如:window.onresize() 事件、mousemove 事件、上传进度等情况。
6、如何判断数组(可换成:遍历的方法、reduce参数,求平均数)
zhuanlan.zhihu.com/p/80405749 字符串方法
www.jianshu.com/p/ec79c4e47… 数组方法
// ES6中增加的数组方法
Array.isArray()
// 使用constructor判断
function isArray(arr) {
return arr.constructor.toString().indexOf("Array") > -1;
}
function isArray(arr) {
return arr.constructor === Array;
}
// 用instanceof判断
function isArray(arr){
return arr instanceof Array;
}
7、如何理解闭包(怎么实现定时器、延时器函数句柄传参)
对闭包的理解:
-
什么是闭包?函数和函数内部能访问到的变量的总和,就是一个闭包。
-
如何生成闭包? 函数嵌套 + 内部函数被引用。
-
闭包作用?隐藏变量,避免放在全局有被篡改的风险。
-
使用闭包的注意事项?不用的时候解除引用,避免不必要的内存占用。
为什么有闭包的这种特性:如果形成闭包,外部函数执行完后,其中的局部变量可能被内部函数使用,所以不能销毁,因此内部函数能一致访问到这些局部变量,直到引用解除。
为什么需要闭包?隐藏变量,避免放在全局有被篡改的风险。
闭包的缺点:使用时候不注意的话,容易产生内存泄漏。
8、使用new创建对象的过程是什么样的(各个函数对象 显示原型prototype和隐式原型__proto__的关系,constructor)
- 首先创建了一个新的
空对象 设置原型,将对象的原型设置为函数的prototype对象。- 让函数的
this指向这个对象,执行构造函数的代码(为这个新对象添加属性) - 判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。
9、Typescript中type和interface的区别是什么
10、讲讲Typescript中的泛型?
11、比较一下history和hash这两种路由
12、Vue.nextTick的实现
- 接收callback放入callbacks中
- 根据当前的浏览器环境选用对用的异步事件API 创建一个异步执行函数timerFun,选用的优先级如下
- Promise.then
- MutationObserver
- setImmediate
- setTimeout
- 执行timerFun将callBacks注册进事件队列
- 事件循环执行到对应的宏任务或者微任务时依次执行callbacks中的回调
13、react diff算法
React的diff算法基于两个假设:
1、不同元素的类型会产生不同的树
2、开发者可以通过key prop标识一个元素在不同的渲染下可以保持稳定(及相同key的元素不需要更新整个元素,不同的key需要更新整个元素)
基于上述假设,React认为在视图更新前后,如果两个节点的Tag名(对于原生标签)或者组件(对于自定义组件)相同,则它们是同一个节点,而且如果是不同的根节点,那么子节点也不需要对比,直接用新树替换掉旧的树即可。
对比的过程
1、当一个组件触发更新(setState),则React会diff以这个组件为根节点的整个虚拟DOM树,对比更新后的虚拟DOM和更新前的虚拟DOM。
2、如果两个节点不同,则用新的节点替换掉旧的节点;如果两个节点相同(假设为oldNode和newNode),则对比它们的属性、innerText和子节点。
3、如果oldNode有某个子节点someOldChild,而newNode没有这个子节点(即newNode没有一个子节点,和someOldNode有相同的tag名、自定义组件引用或者key值),则删掉someOldChild;如果newNode有某个子节点somNewChild,而oldNode没有,则添加someNewChild;如果oldNode和newNode都有某个节点someChild,则将其移动到正确的位置,并递归地进行对比工作,即以someChild为根节点对比新旧两棵虚拟DOM树。
从上面的对比过程可以看出,React的diff(其实Vue也是一样)并不会考虑到节点跨层移动的情况,因此有些观点认为React的对比过程可以描述为“按层比较”(level by level)。
14、Cookie、sessionStorage、localStorage 的区别
相同点:
- 存储在客户端
不同点:
- cookie数据大小不能超过4k;sessionStorage和localStorage的存储比cookie大得多,可以达到5M+
- cookie设置的过期时间之前一直有效;localStorage永久存储,浏览器关闭后数据不丢失除非主动删除数据;sessionStorage数据在当前浏览器窗口关闭后自动删除
- cookie的数据会自动的传递到服务器;sessionStorage和localStorage数据保存在本地
15、介绍下304过程
-
a. 浏览器请求资源时首先命中资源的Expires 和 Cache-Control,Expires 受限于本地时间,如果修改了本地时间,可能会造成缓存失效,可以通过Cache-control: max-age指定最大生命周期,状态仍然返回200,但不会请求数据,在浏览器中能明显看到from cache字样。
-
b. 强缓存失效,进入协商缓存阶段,首先验证ETagETag可以保证每一个资源是唯一的,资源变化都会导致ETag变化。服务器根据客户端上送的If-None-Match值来判断是否命中缓存。
-
c. 协商缓存Last-Modify/If-Modify-Since阶段,客户端第一次请求资源时,服务服返回的header中会加上Last-Modify,Last-modify是一个时间标识该资源的最后修改时间。再次请求该资源时,request的请求头中会包含If-Modify-Since,该值为缓存之前返回的Last-Modify。服务器收到If-Modify-Since后,根据资源的最后修改时间判断是否命中缓存。