前端面试笔试题汇总加自我理解
面试被虐,深感自身不足,基础概念,加深理解,加上思考!全手动码字!Offer会有的,面包会有的!渣硕会变成不渣的。☺️
html语义化
1. 含义
为了良好的结构,在合适的位置使用合适带有语义的标签,使得开发者能够开发出更优雅便于阅读的界面,更有利与适应于多设备和浏览器爬虫和解析页面。
2. 优点
1. 使得页面在没有css的情况下,也能展现良好的风格。
2. 便于阅读和二次开发。
3. 更有利于搜索引擎优化和爬虫。 why? 搜索引擎能够更快更好分析出页面结构,找出需要的资源像图像、视频、音频等,并且打上自己的标签。(识别出该资源)
4. 能够适应于其他设备(盲人阅读器,移动端)。
html5中新增的标签
- header 页眉
- nav
- section 和div相似
- article 引用外部
- aside aside和article一般配合使用,辅助区域,右侧工具栏。
- footer 从页面头部到底部增加的一些标签,闭合、为块状元素。
- fgroup 对h1-h6标签进行组合
- time
- address
- datalist 以上为表单中新增的元素
- audio
- video
- embed
- source 以上为视频音频中新增
- canvas
<embed src = "" height = "" width="" /> <audio preload="preload" controls = "controls" loop="loop" > <source src ="" type = "" /> </audio>
CSS3中新增的属性
将CSS3中新增的属性分为几个模块:选择器、边框和背景、文字、2D和3D、动画、多列布局、盒子模型。
CSS选择器:
1.元素选择器 2.属性选择器 3.伪类选择器。
伪类选择器分为几种:
1.描点伪类::link :visited :hover :active 按照爱恨原则排序,否则会出现混乱。
2.用户行为伪类: :hover :active :focus
3.元素状态伪类:主要针对于form表单 :enable :disabled -> input text元素 :checked :unchecked -> input checkbox
4:nth选择器:first-child last-child nth-child nth-last-child nth-of-type nth-last-of-type first-of-type last-of-type only-child only-of-type
5.否定选择器 :not
6.伪元素 ::first-letter ::first-line ::selection标识文本选中效果:background和color ::before ::after
标准盒子模型和IE盒子模型
content -> padding -> border -> margin
标准盒子模型计算宽度:content
IE盒子模型:content.width + padding + border 如何控制使用哪种模型?什么属性:box-sizing: border-box(IE) 在width内绘制padding\border | content-box(W3C) | inherit。
利用border属性画出一个三角形:
div{ height: 0px; width: 0px; border: 50px solid white; border-top-color: red; border-bottom: none }
border属性:可以用来绘制圆形、三角形、椭圆、平行四边形、梯形。
#圆形 div{ width:50px; height:50px; background:red; border-radius:25px; } #椭圆 div{ width:100px; height:50px; background:red; -webkit-border-radius:50px 25px; -moz-border-radius:50px 25px; border-radius:50px 25px; } #等边三角形 div{ width:0px; height:0px; border-left:50px solid transparent; border-right:50px solid transparent; border-bottom:100px solid red; } #直角三角形 div{ width:0px; height:0px; border-top:50px solid red; border-right:50px solid transparent; }
输入一个网址,到最后显示出页面的过程。
这篇文章写的很全面:https://www.jianshu.com/p/71cf7f69eca8
大致的过程如下:
- 浏览器接受url,url包括:协议、网络地址、端口、请求参数等。
- 浏览器判断是是否有缓存,缓存是否过期,如有直接跳至第8步。
- 如果网络地址不是IP地址,需要进行DNS解析域名,返回一个IP地址。
- 根据IP地址,建立TCP连接。
- 浏览器向服务器发送HTTP请求。
- 服务器接受请求,从它的文档空间里查找资源并返回HTTP响应。
- 浏览器根据返回的HTTP的响应的headers的状态码,进行相应的处理。
- 根据返回的相应,看该资源是否可以被缓存。
- 解码,如果内有js/css等静态资源,需向服务器再发送请求。
- 根据返回的html构建出Dom树,根据css构建出相应的css规则树,渲染页面。
- js中也会出现对dom树的操作,进行回流和重绘,重新渲染,确定相应布局。
- 绘制界面。
需要知道的一些问题:
js的阻塞解析特性
html解析器是自上而下,当遇到例如script、link之内的标签时,就会去相应下载资源,这样会阻塞html解析器继续向下执行。这就是为什么一般将javascript放在</body>标签之前,这样还是会影响页面的显示。
无阻塞脚本技术,现在script标签支持async和defer标记,对于外联的,表示可以异步的下载,等下载完成后再执行。还可以动态加载脚本,创建dom元素。这样可以加快页面响应的速度。
function loadScript(url,callback){ var script = document.createElement("script"); script.type = "text/javascript"; if(script.readyState){ script.onreadystatechange = function(){ if(script.readyState = "loaded"|| script.readyState =="complete"){ script.onreadystatechange = null; callback(); } } }else { script.onload = function(){ callback(); } } script.src = url; document.getElementsByTagName("head")[0].appendChild(script); }
其他关于dns查询ip、TCP三次握手与四次挥手、http一些常用状态码、浏览器缓存机制cache-control、last-modified、etag、expires等在文章里都有讲。
js闭包
要说闭包,先要提到js的作用域。js的作用域ES5中,为全局作用域,和函数作用域。在ES6中增加了块级作用域。
作用域提升:对于var变量,在申明之前就使用了它,会出现作用域提升的现象,输出时值为undefined。但是let,const不允许出现,之前用回出现referenceError。
需要注意!变量不用var声明,默认为全局变量。
暂时性死区:对于块作用域,只要在内部声明了let,即不受外部影响,const同样。
闭包为1.可以访问函数内部的变量的函数。
2.定义在函数内部的函数。
3.是连接函数内部与外部的桥梁,为了解决函数作用域的问题。
4.使变量维持在内存中。
function A(){ var a = 1; function B(){
console.log(a);
}
return B; }
var ww = A();
ww();
闭包使得变量一直保存在内存中,在函数结束后不会被销毁,滥用闭包会造成性能问题,在IE内存会泄漏。注意使用,会改变父变量的值。
解决方式:局部变量在用完之后,退出函数之前删除。
React生命周期函数
- 实例化
- 存在期
- 销毁期
初始实例化阶段:
1.getDefaultProps( ) 只调用一次
2.getInitialState() 在内部可访问props内的变量
3.componentWillMount() 最后可以修改state的机会
4.render()
5.componentDidMount() 已经绘制,可以访问真实DOM
存在期:更新
1.componentWillReceiveProps
2.shouldComponentUpdate false即不执行下面的更新 this.forceUpdate()
3.componentWillUpdate
4.render
5.componentDidUpdate 可以访问真实DOM
销毁期:
willComponentUnmount() 在didMount中注册的事件在这里删除。
React的虚拟Dom
MVVM的模式,将状态和视图进行绑定。
1.在JS中构建出虚拟的DOM。
2.将虚拟的DOM应用到真实DOM中,绘制出页面。
3.当发生变更时,进行DOM diff算法,比较出差异后应用到真正的dom树。
Dom diff具体算法:
原来进行树遍历需要O(n^3),在React的Dom diff中,大胆假设不会发生层级间节点的移动,只对相同层的节点进行比较。
Tree diff,即对相同层的节点比较,只会发生删除、增加、移动操作。如果出现了跨层级的操作,会影响React的性能,所以不推荐进行跨层级的Dom操作。
Component diff算法,如果是同一组件,继续向下比较 Dom tree,如果不相同则判断为dirty component替换到下面所有的组件,如果确定没有发生变化,则可以使用shouldComponentUpdate的方法进行阻止更新。
Element diff算法,提供删除、插入、移动方法,同时提供一直机制就是为所有的element增加唯一的key,如果新集合中的元素老集合中也存在,通过比较MountIndex和lastIndex,如果MountIndex < lastIndex 即进行移动。但是当出现尾部的元素突然移动到首部时,该元素不移动,其他元素移动到该元素后的现象。
所以在React中应尽量避免跨层的Dom操作,并且尽量减少最后一个节点移动到最前的操作,当节点数量过多或更新操作太过频繁时会影响性能。
跨域
1. jsonp
2.script img
3.window.name + iframe
4.document.domain
5.postMessge
6.cors 跨浏览器同源策略
7.websocket
行内元素与块级元素
块级元素
1.元素占一行
2.可以设置行高和内外边距
3.宽和浏览器大小相同,与内容无关
4.内部可以包括行内元素、块级元素
行内元素
1.元素和其他行内元素在一行
2.不可以设置高,但是替换元素img、input可设置
3.宽度与内容有关
4.容纳文本和其他行内
inline-block:既具有block可以设置宽高,又具有inline的不换行的特性。
Promise异步编程
Promise本质上是一个构造函数,支持的方法有race、all,同时原型有then,catch等方法。
Promise定义的异步调用的过程有1.pending(未处理,正在请求)2.resolved(已解决)3.rejected(已拒绝)
将对象的状态和回调函数分离开来。
var promise = new Promise(function(resolve,reject){})接受,在内部可以进行相应处理。
then方法可以接受到返回的结果,并处理,并返回一个promise对象,这样可以进行一个链式调用。
prototype 和 _proto
显式原型和隐式原型
每个函数在创建之后都会拥有一个prototype的属性,指向该构造函数的原型对象。作用:实现对象的继承和属性的共享。
万物皆对象,函数也是对象,也有_proto的属性。
隐式原型,每个对象都是隐藏的_proto的属性,在浏览器中可以访问。作用:通过构成原型链,可以依据原型链访问属性。
对象的proto等于它的构造函数的prototype。
Delegate函数
delegate函数为指定元素(被选元素的子元素)添加一个或多个事件处理并绑定函数。
$("div").delegate(element,eventtype,data(可选),function);
Redux 与 Flux
当React中的组件越来越多时,需要一个特定的管理方式来管理这些state。
Flux是一个框架,也可以说是一种思想,既可以应用于React也可以应用于其他框架。
action-->dispatcher-->store-->view -->action指向dispatcher,dispatcher是最重要的部分,将其他部分的逻辑统一在内部,dispatcher发送action给store,store处理与自己有关的事件,调用change方法,告诉已经controller-views状态发生改变,调用setstate方法,重新渲染。
与Redux比较,Redux只有一个Store方法,主要的关键是Reducer函数,可以有多个Reducer函数,之后可以通过CombineReducer合并成一个。参数会state,action,最后返回newState。
Redux中单向数据流的概念?只能从一个方向来修改状态,状态可预测,可以被操作,状态变化通过手动调用通知,没有“暗箱”操作。
同时是单向绑定,Model绑定到View,Js操作改变Model,从而改变View。
双向数据流(双向绑定):Model可以修改其他Model中的状态,用户的操作也可修改状态。改变一个状态,可能会触发一连串的状态,使状态不可预测。
MVVM(AngularJs):view <-> viewModel 双向绑定,用户操作view,viewModel随之变化。
在单向的层次上,如果用户更改了view,model数据也改变。
js中"=="与"==="
等于与严格等于 == 会进行隐式的类型转换
"=="
vue的声明周期函数:
beforecreate:在观测数据、初始化事件之前调用。 获取不到this.data
created: 实例创建完成,数据已绑定,但是dom还没有生成 $el属性还没有
beforemount: dom已创建、$el属性已有,但是还没有挂载
mounted: 已挂载
beforeupdate
updated
activiate
deactiviate 和keep-alive配合使用 - 控制update
beforedestory
destoryed