JD为什么又给了一次面试,奇怪?
一、vue2中对哪些数组方法做了改动,为什么。换另一种问法就是会改变原数组的方法
1. 首先是7种方法,尾添加和尾删除 push和pop,头添加和头删除 unshift和shift,改变顺序的两个 sort和reverse,最后一个splice
2. vue2中实现响应式,核心是Object.defineProperty(),这个API针对的是被监听对象的属性,里面有get和set方法,这样可以做到对数组每一项的监听。vue3中使用proxy来做响应式,针对的是整个被监听的对象。按照vue2官方,它无法监听到属性的添加和删除。emmmmm.....,具体原因看官网和其他文章吧v2.cn.vuejs.org/v2/guide/re…
二、splice方法
1. splice是删除或添加元素,会改变原数组。参数为start,要删除的个数,以及要添加的元素。如果不传任何参数,则相当于不删除,大于数组长度相当于从数组末尾开始,除此之外都以0开始。删除的个数如果是undefined,负数和0,则不删除,此外如果不传或者超出数组长度则删除至数组末尾。剩余的参数就是往数组内插入的元素,表现行为是在start处向前插入。
三、flex:1 表示什么
1. 它是三个属性的缩写,分别是 flex-grow flex-shrink 和 flex-basis
2. 从后到前说明,flex-basis是定义弹性元素的基础大小,它的值可以是具体的大小,例如:20px,50%这样,也可以是auto,content,max-content这些关键字。它的优先级比width高
3. flex-shrink是压缩比例,它的值只能是一个数字。表示如果弹性元素的宽度大于父元素,就要对弹性元素压缩。计算方式为,看该压缩值占所有元素压缩值的几分之几,乘基础宽度,就是要压缩的宽度。
4. flex-grow是伸展比例,表示子元素要如何分配父元素的剩余空间。计算方式和上面类似
5. flex:1,就表示flex-grow为1,flex-shrink为1,flex-basis为0%。
四、移动端适配方案
1. 首先是rem方案。其本质是等比缩放,通过一个锚点,即html标签的字体大小,让所有的rem单位的元素都可以发生变化。通常会引入flexable.js,来动态改变根节点字体大小。具体看看:yanhaijing.com/css/2017/09… caibaojian.com/flexible-js…
2. 还有就是vw和vh,本质是基于窗口大小的百分比。100vw或100vh就是100%的视窗宽度和高度
3. 这期间问了一个问题是横屏怎么办。我的想法是媒体查询,不同屏幕尺寸下定义不同的效果。但面试官的本意应该是想引出下面的内容
4. 除了vw和vh,还有另一种单位vmin和vmax,它的意思取vw和vh中的最小值和最大值。用这个单位不至于元素在横屏状态下会撑满屏幕。详见juejin.cn/post/725640…
5. 面试官提到字节的一种方案,通过改变meta标签上的设备属性入device-width来实现。不太懂,我也还没有搜到,等搜到再记录
6. 除此之外就是css中的flex,gird, 媒体查询,column多列布局
五、实际开发中要怎么使用rem和vw
1. 肯定不是自己去写或者算,要使用px2rem和px2vw两个插件。通常设置值为屏幕宽度750,方便和设计稿进行转换。
2. webpack本身是用来处理js文件的,对于css,vue,html这类文件就需要对应的loader。处理css文件就需要css-loader。但项目中一般还会使用sass和less这类预处理文件,这就需要less-loader和sass-loader处理。另一方面为了使css属性适配不同的浏览器环境,要对里面的内容进行处理,为了做这些事情就需要postcss-loader。当然它还可以对css做代码合并压缩等。而px2rem和px2vw这两个插件就是在这里作用,对css文件内容做处理
六、type和interface的区别
1. type通常用来定义单个类型,或者联合类型,交叉类型,或者你想把一个类型起别名时可以用到。interface官方叫做接口,通常是像JS中的一个对象,有多个属性时可以用
2. 其实最大的区别是type不可以重名,interface可以重名。重名的interface相当于合并拓展。interface中用extends实现继承,type用& — 交叉类型来实现类型效果
七、app和H5怎么通信
1. 一种是jsBridge,一种是postMessage,还有就是协议拦截,具体可以看
八、编程题,要求是有一个任务队列,最快的方式清空这个任务队列,一个任务执行结束后就去执行另一个任务
const tasks = [
function () { return new Promise(function (resolve, reject) { setTimeout(function () { console.log(0) resolve(0) }, 2000) }) },
function () { return new Promise(function (resolve, reject) { setTimeout(function () { console.log(1) resolve(1) }, 1000) }) },
function () { return new Promise(function (resolve, reject) { setTimeout(function () { console.log(2) resolve(2) }, 5000) }) },
function () { return new Promise(function (resolve, reject) { setTimeout(function () { console.log(3) resolve(3) }, 3000) }) },
]
1. 思路是用一个函数接收一个任务,内部取执行任务并判断任务执行成功后递归的方式执行下一个任务。需要有一个值记录当前应该取第几个任务。最简单的代码如下
let index = 2
const fn = (task) => { const p = task() p.then((res) => { if (tasks[index]) { fn(tasks[index]) index++ } }) }
fn(tasks[0])
fn(tasks[1])