JS篇
1,深拷贝与浅拷贝
2,讲一下for in和for of
3,Js执行机制
4,ES6常用哪些新增方法
5,async/await、Promise、回调函数区别
6,this指向和修改this的方法
7,bind、apply、call区别
8,DOM事件流
9,attachEvent和addEventListener区别
CSS篇
1,float实现双飞翼布局
2,怎么定义一个动画
3,flex布局和grid布局
4,媒体查询
5,清除浮动的方法
6,BFC
HTML篇
1,属性href和src区别
2,HTML标签分类
3,cookie,sessionStorage,localStorage区别
4,重绘与回流
5,DOM和BOM
Vue篇
1,计算属性和监听属性区别?
2,组件如何跨项目?
3,$nextTick()原理?
4,vue父子组件钩子函数的执行顺序?
5,vue自定义指令?
6,vue的mixin?
7,vue中在created和mounted阶段所处理的内容?
React篇
1,react的生命周期?
2,react HOC组件?
3,react中redux实现异步?
4,react Hook中useEffect,useLayoutEffect区别
小程序篇
1,wx.request异步问题
2,openId和unionId区别
3,微信用户授权窗口被用户拒绝后,下次不会弹出问题
参考答案
JS篇
1,深拷贝和浅拷贝的主要区别点是在于 引用类型。
可以先说说什么是基本类型和引用类型?
基本类型:变量在对应内存区中以值的形式存放。
引用类型:变量在对应内存区中以引用地址的形式,数据本身是在地址对应内存区中存放的。
浅拷贝:指对引用类型引用地址的拷贝。
浅拷贝方法:= 号赋值、Object.assign(obj)非嵌套的基本类型,Object.assign({},obj)、concat、slice、扩展运算符 针对嵌套的引用类型;
深拷贝:指创建新的对象类型,对原对象类型的属性和引用地址完全拷贝。
深拷贝方法:Object.assign({},obj)、concat、slice、扩展运算符 针对非嵌套的基本类型。JSON.parse(JSON.stringify())是对变量中属性值为非函数、非undefined的拷贝。还有递归可实现深拷贝。案例如下:
slice()
Object.assign()
扩展运算符
concat()
JSON.parse(JSON.stringify())
2,for of 是遍历数组的值。不能遍历普通对象,因为普通对象不可迭代。for in可以遍历对象和数组,遍历的是key。
3,js是单线程语言(主要用来处理用户交互和DOM操作,单线程也避免了很多复杂性和同步问题)。
js可以将任务分为同步任务(主线程上排队执行的任务)和异步任务(进入Event Table等待主线程中的任务执行完再进入主线程执行)
这些异步任务又可以细分为:宏任务,微任务
宏任务:
console.log('1')
setTimeout(()=>{
console.log('2')
},1000)
setTimeout(()=>{
console.log('3')
new Promise((resolve)=>{
console.log('4')
resolve()
}).then(()=>{
console.log('5')
})
})
console.log('6')
new Promise((resolve)=>{
console.log('7')
resolve()
}).then(()=>{
console.log('8')
})
async function fn(){
console.log('9')
await fn2()
console.log('10')
}
fn()
function fn2(){
console.log('11')
}
console.log('12')
//结果打印:
// 1
// 6
// 7
// 9
// 11
// 12
// 8
// 10
// 3
// 4
// 5
// 2
总结一下:整体代码自上而下先执行主线程任务,如果遇到异步任务(宏任务)被分发到(宏任务)Event Queue,遇到微任务new Promise后直接执行,then被分发到(微任务)Event Queue,遇到async先执行await上方代码(类同步),再执行await 的函数(await函数后是微任务分发到(微任务)Event Queue),然后跳出async,往下继续执行后,主线程空闲,开始第二轮去读取Event Queue(已经注册过的异步任务回调函数),先执行微任务(微任务优先级高于宏任务),再执行宏任务,宏任务执行结束后,检查是有微任务,有继续执行完所有微任务,待主线程闲置,再检查是否有(宏任务)Event Queue未执行,反复执行就形成了事件循环(Event Loop),异步任务执行结束,更新页面。
简单来说:整体script(宏任务)进入主线程自上而下执行,遇到异步任务先分发至对应回调函数队列中(Event Queue),执行完同步任务。第二轮主线程去读取回调函数任务先执行完所有微任务,再执行宏任务,宏任务执行结束检查微任务,开始重复第二轮,异步执行结束,更新页面。
4,let和const,(let和const是块级作用域,const定义的基本类型不可修改,var 存在变量提升)模板字符串,箭头函数,对象键值重名简写,解构,promise对象,展开运算符,module模块
5,async/await、Promise、回调函数都是实现异步的方式,当多个嵌套时回调函数会出现回调地狱问题,promiseES6中提出的,可通过then实现多层链式调用,ES7中提出的async/await,于promise语法相对于promise繁琐的链式写法,以同步方式实现异步的效果,避免了嵌套和链式,代码更简单直观。
6,this指向:谁调用函数,函数中的this指向谁,全局范围内指向window,修改this的方法有:call、apply、bind
7,call和apply的区别在于接收的参数不同,apply第二个参数是数组的形式,call和bind语法一样,执行时机不同,call会立即执行,bind返回值函数被调用时执行。
8,dom事件流分为三个阶段:1,捕获阶段(从document到具体元素,由外到内触发);2,目标阶段;3,冒泡阶段(从具体元素到document,由内到外触发)。代码执行时只会触发捕获和冒泡其中的一个阶段,事件委托就是利用了事件冒泡,onclick 和IE的 attachEvent只能得到冒泡阶段,addEventListener 第三个参数为 true时表示处于捕获阶段,为false时表示处于冒泡阶段,阻止冒泡的的方法e.stopPropagation()
9,(1)attachEvent 只支持IE,addEventListener 不支持IE
(2)attachEvent有两个参数,第一个参数 事件类型 带on;addEventListener有三个参数,第一个参数事件类型不加on,第三个参数是否事件捕获冒泡,true捕获,false冒泡
CSS篇
1,三列都float:left,左右两侧设置负margin值,中间部分嵌套一个元素设置左右margin。
2,(1)transform转换通过几个函数对元素变换(2)transition过渡定义属性的开始和结束状态后需要触发事件,触发一次执行一次(3)animation动画 设置动画的属性值,通过@keyframes关键帧定义动画内容,可重复
3,flex弹性盒,通常子元素一行内显示,从左到右,主要以主轴或侧轴的行列布局。grid网格布局,布局效果和flex类似,也比flex更好用和强大,以行和列多个格子的二维空间,可单独设置某一行或列中的格子,对于一些复杂的布局gird布局可以更简洁的实现。
4,css3对@media进行了扩展,它们并不查找设备类型,而是关注设备的能力。可检测视窗宽高,朝向,分辨率。根据媒体类型制定自适应显示。
5,清除浮动:(1)父元素添加高度或添加overflow,(2)使用after伪元素或before双伪元素,(3)父元素中添加空div 添加clear:both
6,BFC是页面中一个隔离的独立容器,容器内的元素不影响外边。overflow的值非visible,float的值非none,position的值非static或relative,以及display的值为inline-block、table-cell、flex、table-caption或者inline-flex时就会出现BFC。BFC也可以用来避免margin重叠,自适应布局,清除浮动。
HTML篇
1,href 表示超文本引用,是在当前元素和引用文本之间建立关联,浏览器会引用文本文件,并行下载和当前文档的处理。
src 表示资源引用,是引用资源嵌入到文档当前元素所在位置,浏览器会暂停其他内容的处理,直到该资源加载完毕,所以经常把src引入的js文件放在底部。
2,分为三类:(1)行内元素,display:inline,垂直方向padding margin无效,不占独立区域(2)块级元素 display:block 每个元素独占一行,可设置内外边距(3)行内块元素 display:inline-block 元素之间默认有边距。
3,cookie可设置失效时间,方便与服务端通信,长度有限4kB,安全性不高。sessionStorage保存在当前会话窗口内,当前浏览器关闭之前有效,localStorage为持久化保存自客户端,永久存储数据,除非手动清除数据。
4,重绘:当一个元素的外观属性改变所触发的浏览器行为就会产生重绘,如color,background。回流:当一个元素的宽高,布局,显隐改变导致页面重新构建,就产生了回流。回流的成本比重绘更高。
5,DOM文档对象模型:为了操作文档出现的,document是其中一个对象。BOM浏览器对象模型:为了操作浏览器出现的,window是其中一个对象。
Vue篇
1,computed:以return使用,计算的结果默认会被缓存,只有相关属性更改后才重新计算,和其他属性是多对一的关系,也不适合做异步请求。
watch:可以不写return,不支持缓存,和其他属性是一对多的关系,可以执行异步操作。
2,vue项目中会出现相似组件,这时候就可以把公共部分抽离出来借助slot插槽,把组件插件化发布至npm
3,nextTick是等到下次DOM更新结束之后执行延迟的回调函数,当修改数据后使用$nextTick,可以获取到更新后的DOM。原理vue的DOM更新是异步的,监测到数据变化后,vue开启一个队列,把同一个事件循环中数据变化去重后放进队列中,然后在下一次事件循环开始时,清空队列并更新DOM。所以当修改数据时,DOM不会立即更新,而是进入事件循环中等待同一事件循环中的所有数据更新之后,统一更新视图。nextTick是延迟回调来获取更新后的DOM,类似setTimeout。
4,vue中父子嵌套组件的生命周期执行顺序:父组件BeforeCreate—>Create—>BeforeMount—>子组件BeforeCreate—>Create—>BeforeMount—>Mounted—>父组件Mounted。
5,vue代码复用和抽象形式是组件,有些时候你仍需要对普通DOM进行底层操作,这时候就用到了自定义指令。首先注册一个全局自定义指令,页面中通过 v -“指令name” 使用。
6,mixin来分发vue组件中可复用的功能,以js对象形式定义,当组件使用mixin时,所有mixin对象中的项将混入组件本身中,以此提高复用性,可维护性。mixin特点:1,mixin引入到组件后,只被当前组件识别,修改后不会共享到其他组件。2,mixin混入到组件合并过程中,冲突项合并时除钩子函数会优先以组件内为主,mixin中钩子函数也会在组件相同钩子函数之前执行。
7,created:实例创建完成,处理数据监听,计算属性,方法,事件/侦听器,并配置数据监听,计算属性,方法,事件/侦听器的回调函数。
mounted:实例挂载完成,模板渲染成html结束,页面初始化完成。
React篇
1,初始渲染阶段componentWillMount,componentDidMount(2)更新阶段shouldComponentUpdate,componentWillUpdate,componentDidUpdate(3)卸载阶段componentWillUnmount。注componentWillReceiveProps 父组件改变props传值时触发的函数。
2,react高阶组件:是通过一个函数实现,接收一个组件作为参数返回一个新的增强组件。实现方法:(1)属性代理,定义一个函数接受一个组件,基于闭包。构造出新的组件把原组件当作属性使用(2)反向继承,新组件继承原组件从而在内部对组件进行修改。
3,redux中异步通常使用中间件来实现,redux-thunk,使用高阶函数判别action的类型,action是函数时,调用这个函数。
4,区别是调用时机不同,useEffect函数会在浏览器完成布局与绘制之后,在一个延迟事件中被调用(异步执行)。在浏览器执行绘制之前,useLayoutEffect内部的更新计划将被同步刷新。useLayoutEffect会在所有DOM变更之后同步调用effect,可以用它来读取DOM布局并同步触发重渲染(同步执行)。
小程序篇
1,小程序中执行wx.request的时候会发现还没success后面的代码已经执行了,说明js文件执行不是等wx.request后再往下的,而是是异步的,wx.uploadfile也是一样,这个时候可以用promise做一下封装,来实现同步效果。
2,OpenID:用户在当前小程序的唯一标识,UnionID:用户在微信开放平台账号下的唯一标识,即在微信开放平台账号下的不同应用,UnionID相同。
3,微信用户授权窗口被用户拒绝后,下次不会载弹出窗口,需要先判断用户授权状态,调用微信小程序设置后手动弹出授权窗口。