------------恢复内容开始------------
前端14个大厂1周面试题,跳槽稳稳地
前端开发掌握的知识点内容摘要:
HTML&CSS:浏览器内核、渲染原理、依赖管理、兼容性、CSS语法、层次关系,常用属性、布局、选择器、权重、CSS盒模型、Hack、CSS预处理器、CSS3动画
JavaScript: 数据类型、运算、对象、Function、继承、闭包、作用域、事件、Prototype、RegExp、JSON、Ajax、DOM、BOM、内存泄漏、跨域、异步请求、模板引擎、模块化、Flux、同构、算法、ES6、ES7、ES8特性、Nodejs、HTTP
框架和类库: ajax、jQuery、Bootstrap、axios、Vue、Vuex、React、element-ui、layui、webpack
一、小米
1、css 实现图片自适应宽高
一般做法如下
1 <style> 2 div{width: 200px; height: 200px} 3 div img{width: 100%; height: 100%} 4 </style> 5 <div> 6 <img src="xxxx.png" /> 7 </div>
但是,如果外层元素的宽高和图片不一致时,会导致图片被拉伸或收缩,巨丑。所以可以让图片的部分填充整个外层元素
1 <style> 2 div{ 3 width: 200px; 4 height: 200px; 5 background: url('xxxx.png') no-repeat; 6 background-size: cover; 7 background-position: center center; 8 } 9 </style> 10 <div></div>
2、讲 flex,手写出 flex 常用的属性,并且讲出作用
flex-direction: row/row-reverse/column/column-reverse 决定主轴的方向(即项目的排列方向)
flex-wrap: wrap/nowrap/wrap-reverse 决定项目排列方式
flex-basis: number|auto|initial|inherit; 规定弹性项目的初始长度。
flex-grow: number|initial|inherit;规定在相同的容器中,项目相对于其余弹性项目的增长量。
flex-shrink: number|initial|inherit;规定在相同的容器中,项目相对于其余弹性项目的收缩量。
flex-flow <flex-direction>|<flex-wrap> 前两者简写形式,默认flex-flow:row nowrap;
justify-content: flex-start/flex-end/center/space-between/space-around 决定项目在主轴的对齐方式
* space-between:两端对齐,项目之间的间隔都相等。
* space-around:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
align-items: flex-start/flex-end/center/baseline/stretch 定义项目在交叉轴上如何对齐
* baseline: 项目的第一行文字的基线对齐。
* stretch(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
align-content: flex-start/flex-end/center/space-between/space-around/stretch 定义多根轴线的对齐方式。如果项目只有一根轴线,该属性不起作用。
3、BFC 是什么
①何为BFC:BFC(Block Formatting Context)格式化上下文,是Web页面中盒模型布局的CSS渲染模式,指一个独立的渲染区域或者说是一个隔离的独立容器。
②形成BFC的条件:
1、浮动元素,float 除 none 以外的值;
2、定位元素,position(absolute,fixed);
3、display 为以下其中之一的值 inline-block,table-cell,table-caption;
4、overflow 除了 visible 以外的值(hidden,auto,scroll);
③BFC的特性
1.内部的Box会在垂直方向上一个接一个的放置。
2.垂直方向上的距离由margin决定
3.bfc的区域不会与float的元素区域重叠。
4.计算bfc的高度时,浮动元素也参与计算
5.bfc就是页面上的一个独立容器,容器里面的子元素不会影响外面元素。
详见https://www.cnblogs.com/chen-cong/p/7862832.html
4、项目里面的前端鉴权是怎么实现的?
使用vuex保存全局状态,并做数据持久化
vuex里面面定义token变量来表示用户是否登录,初始值为 " "
1 import createPersistedState from 'vuex-persistedstate' 2 3 export default new Vuex.Store({ 4 state: { 5 token: '', 6 }, 7 mutations: { 8 setIsLogin(state, isLogin) { //登录成功调用 9 state.token = isLogin; 10 }, 11 FedLogOut(state) { //退出登陆执行 12 state.token='' 13 } 14 } 15 actions, 16 getters, 17 plugins:[createPersistedState({ //vuex数据固化到本地缓存,数据持久化 18 storage: window.localStorage 19 })] 20 });
配置request请求拦截器 request请求拦截器:发送请求前统一处理,如:设置请求头headers、应用的版本号、终端类型等。
1 service.interceptors.request.use( 2 config => { 3 if (store.state.token) { 4 // 为请求头对象,添加token验证的Authorization字段 5 config.headers.Authorization = store.state.token; 6 } 7 return config 8 }, 9 error => { 10 // do something with request error 11 console.log(error) // for debug 12 return Promise.reject(error) 13 } 14 )
response响应拦截器 response响应拦截器:有时候我们要根据响应的状态码来进行下一步操作,例如:由于当前的token过期,接口返回401未授权,那我们就要进行重新登录的操作。
1 service.interceptors.response.use( 2 response => { 3 Toast.clear() 4 const res = response.data 5 if (res.status && res.status !== 200) { 6 // 登录超时,token过期返回401,重新登录 7 if (res.status === 401) { 8 store.dispatch('FedLogOut').then(() => { 9 router.replace({ 10 path: '/login' 11 //登录成功后跳入浏览的当前页面 12 // query: {redirect: router.currentRoute.fullPath} 13 }) 14 }) 15 } 16 return Promise.reject(res || 'error') 17 } else { 18 return Promise.resolve(res) 19 } 20 }, 21 error => { 22 Toast.clear() 23 console.log('err' + error) // for debug 24 return Promise.reject(error) 25 } 26 )
5、vue 里面的虚拟 dom 是怎么回事?
当你用原生js 或jquery等库去操作DOM时,浏览器会从构建DOM树开始讲整个流程执行一遍,所以频繁操作DOM会引起不需要的计算,导致页面卡顿,影响用户体验
虚拟 DOM 的实现原理主要包括以下 3 部分:
-
-
用 JavaScript 对象模拟真实 DOM 树,对真实 DOM 进行抽象;
-
diff 算法 — 比较两棵虚拟 DOM 树的差异;
-
pach 算法 — 将两个虚拟 DOM 对象的差异应用到真正的 DOM 树。
-
6、vue 双向绑定讲一讲
vue的数据双向绑定主要通过Object.defineProperty()方法来进行数据劫持以及发布者-订阅模式来实现的,vue实例化的时候会去遍历所有的属性,给这些属性添加get和set方法进行数据劫持;
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>forvue</title> 6 </head> 7 <body> 8 <input type="text" id="textInput"> 9 输入:<span id="textSpan"></span> 10 <script> 11 var obj = {}, 12 textInput = document.querySelector('#textInput'), 13 textSpan = document.querySelector('#textSpan'); 14 15 Object.defineProperty(obj, 'foo', { 16 set: function (newValue) { 17 textInput.value = newValue; 18 textSpan.innerHTML = newValue; 19 } 20 }); 21 22 textInput.addEventListener('keyup', function (e) { 23 obj.foo = e.target.value; 24 }); 25 26 </script> 27 </body> 28 </html>
使用Object.defineProperty()来定义属性的set函数,属性被赋值的时候,修改Input的value值以及span中的innerHTML;然后监听input的keyup事件,修改对象的属性值,即可实现这样的一个简单的数据双向绑定。
7、手写函数防抖和函数节流
函数节流:不断触发一个函数后,执行第一次,只有大于设定的执行周期后才会执行第二次
1 /* 2 节流函数:fn:要被节流的函数,delay:规定的时间 3 */ 4 function throttle(fn,delay){ 5 // 记录上一次函数出发的时间 6 var lastTime = 0 7 return function(){ 8 // 记录当前函数触发的时间 9 var nowTime = new Date().getTime() 10 // 当当前时间减去上一次执行时间大于这个指定间隔时间才让他触发这个函数 11 if(nowTime - lastTime > delay){ 12 // 绑定this指向 13 fn.call(this) 14 //同步时间 15 lastTime = nowTime 16 } 17 } 18 }
函数防抖:不断触发一个函数,在规定时间内只让最后一次生效,前面都不生效
1 function debounce(fn,delay){ 2 var timer = null 3 // 清除上一次延时器 4 return function(){ 5 clearTimeout(timer) 6 // 重新设置一个新的延时器 7 timer = setTimeout(() => { 8 fn.call(this) 9 }, delay); 10 } 11 }
8、ES6语法比如 promise、class 等等
promise详见https://www.cnblogs.com/Blod/p/15801202.html
class详见https://www.cnblogs.com/Blod/p/15801399.html