本人目前是一名即将毕业应届小菜鸡,面试过程中有些老生常谈的问题也没答上来,当时很恼火,所以不得不写这份面经,以便于时刻提醒自己。因为实习的时候一直用react,vue了解相对较少,所以面试公司技术栈主要是react。步入正题...
html5+css3
1、position都有那些属性,如果一个盒子的子级设置了绝对定位,他基于谁定位.
position: static/absolute/fiexed/relative/sticky; 如果元素设置了绝对定位,他会寻找有定位的父级去进行定位,如果没有,则相对于文档进行定位。
2、如果父级设置了position: static;呢,基于谁定位?(因为很少用到这个,当时没答上来)。
其实
static为该属性的默认值,设置该属性后是遵从常规流,并且其他四个属性也不会被引用。也就是你设置不设置都不用影响其他元素。
3、H5语义化标签有哪些,他们的作用。
header(头部)、footer(底部页脚)、nav(导航)、section(块)、aside(侧边栏)、article(文章),其实这些标签都是div,只是不同名字含义的div
标签语义化的作用(我回答的也不是很完整):
- 当页面丢失样式的时候可以清晰的显示出页面结构。
- 有利于搜索引擎的优化(SEO)。
- 有利于其他设备的解析。(如:盲人阅读器)
- 有利于团队开发和维护,一个大的项目是由很多人共同开发完成的,自己的代码也不是只给自己看,如果有一套标准可以提高团队的效率,也方便后期维护。 SEO:即Search Engine Optimization,它是一种通过分析搜索引擎的排名规律,了解各种搜索引擎怎样进行搜索、怎样抓取互联网页面、怎样确定特定关键词的搜索结果排名的技术
注意:这些标签主要针对的是搜索引擎,并且可以重复使用。
4、弹性盒子和两栏布局,垂直水平居中,盒模型这些都是基础的问题,这里就不一一赘述了。推荐几个链接:blog.csdn.net/weixin_4416… www.jianshu.com/p/d51c63788…
javascript(ES6+)
1、let、const、var区别
var关键字申明变量存在变量提升,提升到全局变量。let和const关键字申明的变量不存在变量提升,并且存在块级作用域,只允许在作用域内使用其变量。const申明的变量一经申明就必须赋值,并且原始类型不可改变,如果为引用类型不可改其地址,地址内的内是可以改变的。
2、简述一下闭包原理和作用
- 但凡内部函数保存到外部一定会生成闭包,闭包会导致原有的作用域链不释放造成内存泄漏。闭包产生的根源是变量提升 作用:
- 实现共有变量
- 可以做缓存(存储结构)
- 可以实现封装,属性私有化
- 模块化开发,防止污染全局变量 注意:闭包会导致多个函数共用一个变量,如果不是特殊需要,尽量避免这种情况发生
3、简述一下原型链原理
原型链主要针对构造函数的,通过构造函数创建实例对象,每个实例对象都会有一个__proto__属性,该属性指向构造函数的prototype属性,该属性也有自己的__proto__,这样层层向上通过__proto__属性连接起来就叫原型链,原型链的最顶端是null。
首先看一张原型链的图表:
再去对比看下面的实例和运行结果,你就会豁然开朗。
4、简述一下事件冒泡原理,怎么去阻止事件冒泡行为
结构上(非视觉上)的嵌套关系,绑定相同的事件后,会存在事件传递功能,自底(事件源对象)向上传递知直到document/window冒泡结束。
- 如下是阻止冒泡的封装:
5、简述一下promise的原理和作用
promise是异步编程的一种方案,他的出现主要是为了解决前端异步函数多层嵌套产生的回调地狱问题,以及回调地狱错误方法不容易捕捉的问题,他有三个状态pending(进行中)、fulfilled(已完成)、rejected(已拒绝)。
- 他的状态一经改变就不会再变化,并且只有两种状态,要么完成,要么拒绝。
- promise的
.then(reloved, reject)方法有两个回调参数,分别代表两种状态,当完成时执行第一个参数,失败时执行第二个参数。 .catch():Promise.prototype.catch:方法具有冒泡性质,会向下一个promise对象传递,直到被捕获为止。
6、简述async和await这两关键字。
如果某个函数前面加了async这个关键字,则该函数就会进行异步加载,并且返回值是一个Promise对象,await关键字必须和async配合使用,意思是等到表达式执行完之后,再进行后面的操作。
7、简述一下事件循环机制(Event Loop) JS引擎对事件队列的取出,执行方式以及和浏览器宿主环境三者之间的配合叫做事件循环。 如图:
- 当JS线程发生了某些变化,如果某些变化存在事件处理程序,会将事件处理函数加入到事件队列的内存里,当JS引擎发现执行栈为空时也就是空闲时,就会从事件队列里取出对应的事件放入到执行栈中去执行。
- 异步函数一定会放入到事件队列里,同步函数只存在于执行期上下文。
- 事件队列里又包含宏任务和微任务,当JS引擎发现执行栈为空时会先将微任务依次执行,然后再执行宏任务。
宏任务:Ajax请求,计时器产生的回调,异步函数。微任务:promise产生的回调。
8、null和undefined的区别
- 首先两者都是Object的派生。
null和undefined不能有属性和方法。null==undefined返回结果为true,但是绝对相等又是false。
原因:
null是object类型,代表一个空对象的指针。但是undefined是undefined类型。
- 原型链的最顶端是
null,或者作为函数的参数,表示该函数的参数不是对象。 - 如果变量申明未赋值,参数未传递就会返回
undefined。函数没有返回值或者return后面没有值,返回值会是undefined - 在判断语句中两者都返回false。
- 两者转换值:
jQuery
1、jQuery.extend()和jQuery.fn.extend()的区别
- jQuery.extend()是在jQuery类上添加类方法(静态方法),
它还可以合并多个对象,跟原生
Object.assign类似,为了不改变原对象通常将第一个参数传一个空对象
- 对于
jQuery.fn.extend(),通过源码可以知道,jQuery.fn = jQuery.prototype所以该方法就相当于在jQuery原型上添加属性和方法,只要是jQuery创建的实例对象都可以调用他添加的方法。
2、jQuery.offset()的含义
获取元素相对于document的位置。
react
1、简述react生命周期(新版)
constuctor
- 组件构造器,构建组件实例对象,同一组件只会运行一次
static getDerivedStateFromProps
- 该函数时静态的,通过参数可以获取新的属性和状态。
- 该函数的返回值会覆盖掉函数的状态。
shouldComponentUpdate
- 该钩子函数能够指示是否需要渲染该组件,通过函数的返回值决定,返回值为布尔值,默认情况返回
true,该函数必须有返回值
render
- 该函数返回一个虚拟DOM,会被挂载到虚拟DOM树中,然后渲染到页面的真实DOM中。
- 该函数中禁止使用setState,因为会造成无限递归渲染
componentDidMount
- 只会执行一次,组件挂载页面之后执行
- 该函数主要做一些网路请求,计时器启动操作,组件状态的初始化工作。
getSnapshotBeforeUpdate
- 真实的DOM构建完成,但还未实际渲染到页面中。
- 在该函数中,通常用于实现一些附加的dom操作
- 该函数的返回值,会作为
componentDidUpdate的第三个参数 - 该函数必须得有返回值,否则会报错,值可以是快照值、null、undefined
componentDidUpdate
- 这个函数执行之前,虚拟DOM已经挂载到页面形成真实DOM,也就是组件修改之后需要做的工作。
- 往往在该函数中进行一些dom操作,改变元素
componentWillUnMount
- 组件在卸载之前所做的工作。通常在该函数中销毁一些组件依赖资源,比如计时器
2、简述一下类组件和hook的区别
- hook就是函数组件,他的状态都是通过参数或者返回值的形式进行传递,避免了繁琐的this指向问题。
- hook可以将业务逻辑抽离出来,逻辑就是逻辑,这样技能提高代码的复用性,减少冗余代码。
- 类组件中不能使用hook。
3、在react中有哪些优化项目的手段
- 类组件中可以使用
shouldComponentUpdate钩子避免不必要的渲染。 - 组件尽可能的拆分、解耦
- 类组件中在constructor中绑定this
- 使用
reactdomserver实现服务端渲染,更快速的渲染 - 在函数组件中可以使用,
useEffect的第二个参数添加依赖项;使用useCallback、useMemo给不需要重复渲染的函数就行缓存和添加依赖性。 - 禁止render函数中进行状态修改。
4、类组件中的setState和hook中的useState钩子改变状态时是替换还是合并(覆盖)。
- 类组件中单个调用
setState新状态会将原来的状态替换。 - 对于
useState,引用官方的一段话:
State 变量可以很好地存储对象和数组,因此,你仍然可以将相关数据分为一组。然而,不像 class 中的
this.setState,更新 state 变量总是替换它而不是合并它。
5、react中父子元素和兄弟元素之间是如何通信的
由于react是单项数据流,并且遵循状态属于谁,谁才有修改的权力,因此共享状态必须父传子,兄弟之间也是通过父组件传递,如果子组件想要修改父组件状态,必须向上抛回调函数,向父组件传递信号,让其修改状态。
6、setState中改变状态是同步还是异步的,当函数内部多次调用setState时会执行几次
- 由React控制的事件处理程序,以及生命周期函数调用setState不会同步更新state 。
- 因为
this.props和this.state可能会异步更新,所以你不要依赖他们的值来更新下一个状态。
例如,此代码可能会无法更新计数器:
解决办法就上将setState的第一个参数变成函数而不是对象。这个函数用上一个 state 作为第一个参数,将此次更新被应用时的 props 做为第二个参数:
-
React控制之外的事件中调用setState是同步更新的。比如原生js绑定的事件,setTimeout/setInterval等。大部分开发中用到的都是React封装的事件,比如onChange、onClick、onTouchMove等,这些事件处理程序中的setState都是异步处理的。
-
如果连续多次调用
setState,会将所有的setState进行合并,等到所有setState执行完之后,再将状态统一处理,最后进行渲染,这也是react内部做的小优化。
7、简述一下虚拟DOM和diffing算法
虚拟DOM其实就是一个JavaScript对象,该对象有type、value、props、children等属性组成,虚拟DOM树就是由多个虚拟DOM组成的一个对象集合,我们都知道react中元素的key值是唯一的,当某的元素的状态发生变化后,就会形成新的虚拟DOM,react内部会将之前的虚拟DOM对象进行对比,改变后的虚拟DOM会覆盖掉之前的对象,并且渲染到真实DOM,否则页面不会发生渲染。
vue
1、v-if和v-show指令的区别
- 两者的共同点:
- 两者都能通过布尔值控制元素的显示与隐藏。
- 两者的不同点:
- 控制手段:
v-show隐藏则是为该元素添加display:none,dom元素依旧还在。v-if显示隐藏是将dom元素整个添加或删除。因此,频繁切换的显示与隐藏应该用v-show, 只判断一次的使用v-if; - 编译过程:
v-if切换有一个局部编译/卸载的过程,切换过程中合适地销毁和重建内部的事件监听和子组件;v-show只是简单的基于css切换。 - 编译条件:
v-if是真正的条件渲染,它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建。只有渲染条件为假时,并不做操作,直到为真才渲染。 v-if可以写在template上,v-show不行,写了也没用。v-show由false变为true的时候不会触发组件的生命周期v-if由false变为true的时候,触发组件的beforeCreate、create、beforeMount、mounted钩子,由true变为false的时候触发组件的beforeDestory、destoryed方法
原文链接:blog.csdn.net/weixin_5751…
其他
1、简述一下你对MVC和MVVM的理解和他们两者的区别
- mvc是model、controller、和view所组成,是为了解决ui复杂度的一种方案,其内部原理是浏览器发送各种请求,服务器接受到不同的请求后,生成不同的controller来处理不同的请求的数据,将处理好的数据传入到model后,model将ui数据处理好以后交给view,然后返回一个完整的html页面,如图:
- MVVM采用双向数据绑定,view中数据变化将自动反映到viewmodel上,反之,model中数据变化也将会自动展示在页面上。把Model和View关联起来的就是ViewModel。ViewModel负责把Model的数据同步到View显示出来,还负责把View的修改同步回Model。
- MVVM核心思想,是关注model的变化,让MVVM框架利用自己的机制自动更新DOM,也就是所谓的数据-视图分离,数据不会影响视图,如图:
原文链接:blog.csdn.net/jiahao1186/…
2、堆和栈的区别
原文链接:blog.csdn.net/qq_29850249…
以上内容有部分知识总结的不是很全面,如果阅读中有错误或者不规范或者需要补充的地方,恳请大家即使指出,大家互相学习,共同进步!!