前端开发常见面试问题及答案整理
前端开发常见面试问题及答案整理
闭包的理解
闭包是为了设计私有方法和变量。
优点:避免全局变量的污染
缺点:闭包常驻内存,加大内存使用,使用不当容易造成内存泄漏
闭包的三大特性:
- 函数嵌套函数
- 函数内部可以引用外部的参数和变量
- 参数和变量不会被垃圾回收机制回收
cookie的弊端
1.每个特定的域名下最多生成20个cookie,每个cookie长度不能超过4KB,否则会被截掉。
2.安全性问题。如果cookie被拦截,那就可以取到所有session信息,即使加密也于事无补,,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。
浏览器本地存储
html5中web storage包括了2种存储方式:sessionStorage和localStorage
- sessionStorage:用于存储本地的一个会话的数据,这些数据只能在同一个会话中的页面才能访问并且当会话结束后会随之销毁。所以sessionStorage不是一个持久化的的本地存储,仅仅是会话级别的存储。
- localStorage:是持久化的本地存储,除非主动删除数据,否则永远不用过期。
web storage和cookie的区别
web storage和cookie类似,区别是web storage是为了更大容量设计的。
cookie大小受限制;且每次打开新的页面,cookie都会被发送过去,无形中浪费带宽;且cookie不能跨域
web storage拥有setItem,getItem,removeItem,clear等方法,而cookie需要自己封装setCookie,getCookie
但cookie是不可或缺的:cookie的作用是与服务器进行交互,作为http的规范而存在,web storage仅仅是为了本地存储
localStorage和sessionStorage都具有相同的操作方法,例如setItem、getItem和removeItem
cookie和session的区别
- cookie存放在客户端浏览器,session存放在服务器
- cookie最大4kb,且每个站点最多20个cookie
- cookie不是很安全,别人可以获取cookie进行cookie欺骗
- session会在一定时间内存储在服务器,当访问量增大时,占用服务器的性能
css相关问题
display:none 和 visibility:hidden
- display:none隐藏对应的元素,文档布局中不再分配空间,周边元素会当他不存在
- visibility:hidden 隐藏元素,保留布局,占用空间。
css中link和@import的区别
- link是html标签,@import是css提供的
- link是html标签无兼容问题,@import需ie5以上才兼容
- 页面加载时,link会被一起加载,而@import需要页面加载完后再加载
- link引入样式权重高于@import权重
position:absolute和float的异同
- 相同点:对内联元素设置position:absolute和float都会使其脱离文档流,并可设置宽和高
- 不同点:设置position:absolute的元素会覆盖文档流中的其他元素,而float仍然占据位置。
box-sizing属性
box-sizing属性用来控制元素的盒模型解析模式,默认是content-box
- content-box: w3c标准盒模型,元素的宽高由padding+border+content决定,设置元素的width/height属性是指content的宽/高
- border-box: IE怪异盒模型,设置元素的width/height属性是指content+padding+border
CSS盒模型本质上是一个盒子,封装周围的HTML元素,它包括:边距,边框,填充,和实际内容。
CSS 选择符有哪些?
- id选择器(#con)
- class选择器(.con)
- 标签选择器(div/p)
- 相邻选择器(div + p)
- 子选择器(div > p)
- 后代选择器(div p)
- 通配符选择器(*)
- 属性选择器(a[rel = “external”])
- 伪类选择器(a:hover)
css哪些属性可以继承?
- 可以继承属性:font-size, font-family,color,text-indent
- 不可以继承属性:width,height,border,padding,margin
所有元素可继承:visibility/cursor
块元素可继承:text-align/text-indent
列表元素可继承:list-style,list-style-image,list-style-type
行内元素可继承:font,font-size,font-family,color,line-height,letter-spacing,word-spacing
css优先级算法?
- 优先级就近原则,同权重情况下样式定义最近者为准
- 载入样式以最后载入为准
- !important > 内联 > id > class > tag,important 比 内联优先级高,但内联比 id 要高
css3新增伪类有哪些?
- p:first-of-type 选择属于其父元素的首个
<p>
元素的每个<p>
元素。 - p:last-of-type 选择属于其父元素的最后
<p>
元素的每个<p>
元素。 - p:only-of-type 选择属于其父元素唯一的
<p>
元素的每个<p>
元素。 - p:nth-child(2) 选择属于其父元素的第二个子元素的每个
<p>
元素。 - p:only-child 选择属于其父元素的唯一子元素的每个
<p>
元素。 - :enabled :disabled 控制表单控件的禁用状态。
- :checked 单选框或复选框被选中。
position的值,分别相对于谁定位?
- static: 默认值,没有定位,元素出现在正常文档流中。
- relative:相对定位,相对于其在正常文档流中位置定位。
- absolute: 绝对定位,相对于最近一级的定位不是staic的元素定位。
- fixed: 绝对定位,相对于浏览器视窗定位。
css3有哪些新特性?
- border-radius:圆角
- border-image: 边框图片
- box-shadow: 边框阴影
- background-image: 多背景
- background-clip: 背景图片绘制区域
- background-origin: 背景图片的定位区域
- text-shadow: 文本阴影
- word-wrap:允许长单词或url换行到下一行
- word-break: 设置自动换行的处理方法
- transform: 旋转、缩放、移动、倾斜,2D或3D转换
- animation: 使用@keyframes创建动画
- transition: 设置元素过渡效果
- column-count/gap/rule: 多列设置
- ::selection: 新增伪元素,设置选中高亮
XML和JSON的区别?
- 数据体积方面:JSON相对XML来说,数据体积小,传输速度更快
- 数据交互方面:JSON于js的交互更方便,更容易解析处理
- 数据描述方面:XML对数据的描述比JSON好
- 传输速度方面:JSON的传输速度要快于XML
对BFC的理解?
BFC块级格式化上下文,是一个独立的渲染区域,内部元素不会影响外部元素定位,使内外元素相隔离
BFC布局规则:
- BFC是一个独立的区域,内外元素不互相影响
- 内部的box会在垂直方向,一个一个排列
- box垂直方向的距离由margin决定,相邻的2个box间的margin会发生重叠
- 每个元素的margin box的左边与border box的左边相接触,即使浮动也如此
- BFC区域不和浮动盒子相重叠
- 计算BFC高度时,float box也参与计算
什么情况会形成BFC?
- 根元素
- position为absolute或fixed
- 浮动元素
- display值为flex、inline-flex、、table-cell
- overflow不为visible的元素
css sprites,如何在网站使用?
css sprites就是把网页中一些背景图片整合到一张图片中,利用”background-image”,”background-repeat”,”background-position”属性组合进行背景定位。”background-position”可以精准定位背景图片的位置。有效减少图片请求开销。
html部分
对语义化的理解?
- 样式丢失也能呈现出清晰的结构
- 有利于SEO:和搜索引擎建立良好沟通,有助于爬虫抓去更多信息
- 方便其他设备解析(屏幕阅读器、盲人阅读器)
- 便于团队开发和维护,语义化更具有可读性
Doctype的作用?严格模式和混杂模式区别?有何意义?
- 声明位于文档最前面,告知浏览器以何种模式渲染文档
- 严格模式的排版和js运作模式是以浏览器支持的最高标准运行。
- 在混杂模式中以宽松的向后兼容的方式显示,模拟老式浏览器的行为以防止站点无法工作。
- DOCTYPE不存在或不正确会使浏览器以混杂模式呈现。
浮动工作原理?清除浮动的技巧?
浮动元素脱离文档流,不占据空间。浮动元素碰到包含它的边框或浮动元素的边框停留。
清除浮动方式:
- 使用空标签清除浮动:浮动标签后面添加一个空标签,定义css clear:both.弊端就是增加了无意义的标签
- 使用overflow:给包含浮动元素的父元素添加overflow:auto;zoom:1;zoom:1;兼容ie6
- 使用after伪对象清除浮动:只适用于非IE浏览器,该方法中必须为需要清除浮动元素的伪对象中设置 height:0,否则该元素会比实际高出若干像素
浮动元素引起的问题和解决方案?
- 1.父元素的高度无法被撑开,影响与父元素同级的元素
- 2.与浮动元素同级的非浮动元素(内联元素)会跟随其后
- 3.若非第一个元素浮动,则该元素之前的元素也需要浮动,否则会影响页面结构
解决方法:
对于第二个第三个问题可用clear:both清除元素的浮动,对于第一个问题,给父元素添加clearfix样式:
1 | .clearfix::after{ |
清除浮动的几种方式:
1 | 1,额外标签法,<div style="clear:both;"></div>(缺点:不过这个办法会增加额外的标签使HTML结构看起来不够简洁。) |
DOM操作——怎样添加、移除、移动、复制、创建和查找节点
创建
- createDocumentFragment() 创建一个Dom片段
- createElement() 创建一个元素
- createTextNode() 创建文本节点
添加、移除、移动、复制
- appendChild()
- removeChild()
- replaceChild()
- insertBefore()
查找
- getElementsByTagName()
- getElementById()
- getElementsByClassName()
html5有哪些新特性?
- 拖拽API
- 语义化更好的标签(header,section,article,footer,nav,aside)
- 音视频(audio/video)
- canvas画布/svg
- 地理位置Geolocation
- 本地缓存:localStorage持久化缓存,sessionStorage会话级缓存
- 新的表单控件:calendar,date,time,url,search,email
常见浏览器兼容问题
- 浏览器默认margin,padding值不同,需要添加全局*{margin:0;padding:0}
- chrome浏览器设置字体小于12px,会默认为12px,解决方法:-webkit-text-size-adjust:none;
- a标签超链接访问过后hover样式就不出现了,被访问过的链接不再具有hover和active,解决方法改变css属性的顺序:
L-V-H-A: a:link{} a:visited: a:hover a:active - 怪异模式问题:漏写DTD声明时,火狐仍然按照标准模式来解析网页,但在IE中会触发怪异模式。
如何实现浏览器多个标签页之间通信?
使用localStorage,cookies等本地存储方式
进程和线程之间关系和区别?
1.定义
- 进程:是系统进行资源分配和调度的独立单位。
- 线程:线程是进程的一个实体,是cpu调度和分派的基本单位,是比进程更小的能独立运行的基本单位。线程自己基本上不拥有系统资源,但是和进程内的其他线程共享进程拥有的全部资源。
2.关系
- 一个线程可以创建和撤销另一个线程,同一个进程中的多个线程之间可以并发执行。
- 相对进程而言,线程更接近于执行体的概念,它可以与进程内的其他线程共享资源,但拥有自己的栈空间,拥有独立的执行序列
3.区别
进程和线程的主要差别是他们是不同的操作系统资源的管理方式。进程拥有独立的地址空间,一个进程崩溃后,基于系统的保护程序,并不会影响其他进程,而线程只是进程中的不同执行路径。
线程拥有自己的堆栈和局部变量,但线程间没有单独的地址空间,一个线程死掉就相当于整个进程死掉,所以多进程的程序比多线程的程序更健壮,但在进程切换时,耗费资源较大,效率低一些。- 一个程序至少有一个进程,一个进程中至少有一个线程
- 线程的划分尺度低于进程,使得多线程的程序并发性高
- 进程在执行过程拥有独立的内存单元,而多个线程共享内存,从而极大的提高程序的运行效率
- 线程在执行过程中和进程还是有区别的。每个线程都有程序运行入口,顺序执行序列和程序的出口,但线程不能独立执行,必须依存于应用程序,由应用程序提供多个线程执行控制
- 从逻辑角度来看,多线程的意义在于应用程序中,有多个执行部分可以同时执行,但是操作系统并没有将多个线程看出多个独立的应用,来实现线程的调度和管理以及资源分配。这就是进程和线程的重要区别
4.优缺点
- 线程执行开销小,但不利于资源的管理和保护;而进程相反
- 线程适合于在SMP机器上运行,而进程则可以跨机器迁移。
什么是FOUC?怎么解决?
Flash Of Unstyled Content 文档式闪烁
- 什么是FOUC(文档样式短暂失效)?
- 如果使用import方法对CSS进行导入,会导致某些页面在Windows 下的Internet Explorer出现一些奇怪的现象:以无样式显示页面内容的瞬间闪烁,这种现象称之为文档样式短暂失效(Flash of Unstyled Content),简称为FOUC。
- 造成原因:
- 使用import引入css
- 将样式表放在页面底部
- 多个样式表放在html结构的不同位置
当样式表晚于页面html加载,当加载到此样式表时,页面将停止之前的渲染,等待文件的下载解析后将重新渲染页面,也就出现短暂页面闪烁
- 解决方法:
- 使用link标签将样式表放置与head中
null和undefined的区别?
null是表示“无”的对象,转为数值为0,undefined是表示“无”的原始值,转为数值为NaN。
当声明的变量未初始化时,值为undefined。
null用来表示尚未存在的对象,常用来表示函数企图返回不存在的对象。
undefined:
1.变量被声明了,但没有赋值,该变量值为undefined
2.调用函数时,应该提供的参数没有提供,该参数值为undefined
3.未给对象的属性赋值时,该属性的值为undefined
4.函数没有返回值时,默认返回undefined
null:
1.作为函数的参数,表明该函数的参数不是对象
2.作为对象原型链的终点
new 操作符具体做了什么?
- 1.创建新的空对象,并且this变量引用该对象,同时还继承了该函数的原型
- 2.属性和方法被加入到this引用的对象上
- 3.新创建的对象由this所引用,并隐式返回this
1 | var obj = {}; |
js延迟加载的几种方式?
js延迟加载就是等页面加载完成后再加载js文件
js延迟加载有助于提高页面加载速度。
一般有以下几种方式:
1.defer属性
html4为script标签添加了defer属性,表明脚本在执行时不会影响页面构造,也就是说脚本会延迟到整个页面都加载解析完毕再执行1
2
3<head>
<script src="test.js" defer="defer"></script>
</head>defer属性告诉浏览器立即下载,但延迟执行。虽然
<script>
元素放在了<head>
元素中,但包含的脚本会延迟到浏览器遇到</html>
标签后再执行。
HTML5规范要求脚本按照它们出现的先后顺序执行
defer属性只适用于外部脚本文件
2.async属性
html5为script标签定义了async属性,与defer属性类似。只适用于外部脚本。
目的:不让页面等待脚本下载和执行,从而异步加载页面其他内容
异步脚本一定会在onload事件前执行
不能保证脚本按照顺序执行1
<script src="test1.js" async></script>
async和defer一样,不会阻塞其他资源下载,不会影响页面加载
缺点:不能控制脚本加载顺序3.动态创建DOM方式
1 | //这些代码应被放置在</body>标签前(接近HTML文件底部) |
创建script,插入到DOM中,加载完毕后callBack
- 4.使用setTimeout延迟
- 5.按需异步加载
document.write和innerHTML的区别
document.write重绘整个页面
innerHTML重绘页面一部分
哪些操作会造成内存泄漏?
内存泄漏是指任何对象在您不再拥有或需要时仍然存在
垃圾回收器会定时扫描对象,并计算应用了每个对象的其他对象的数量,当引用该对象数量为0,或对该对象的惟一引用是循环的,那么该对象的内存就会被回收。
setTimeout函数的第一个参数如果是字符串,闭包、控制台日志,循环(两个对象彼此存在且彼此引用时,会行程一个循环)会引发内存泄漏。
如何判断当前脚本运行在浏览器还是node环境中?
通过判断Global对象是否等于window,如果不是则在node中
this == window
ajax过程
- 1.创建一个XMLHttpRequest对象,也就是异步调用对象
- 2.创建一个新的http请求,设置请求的方式、URL以及验证信息
- 3.设置响应http请求状态变化的函数
- 4.发送http请求
- 5.获取异步调用返回的结果
- 6.使用js和dom实现局部刷新
ie各版本和chrome可以并行下载多少个资源
IE6 两个并发,iE7升级之后的6个并发,之后版本也是6个
Firefox,chrome也是6个
javascript的同源策略
同源:协议、域名、端口相同,同源策略是一种协议,指脚本只能读取来自同一源的窗口和文档属性。
哪些地方会出现css阻塞,哪些地方会出现js阻塞?
所有浏览器在下载js的时候,都会阻塞其他资源的下载,页面的呈现等。直到js下载、解析、执行完毕后才能继续并行下载其他资源并呈现内容。新一代浏览器都支持并行下载js,但仍然会阻塞其他资源(css,图片)的下载。
由于浏览器为了防止出现js修改dom树,造成重新构造dom树的情况,需要阻塞其他资源的下载和呈现
嵌入js会阻塞所有内容的呈现,外部js只会阻塞其后内容的显示,2种方式都会阻塞资源的下载。
css本来是可以并行下载的,在什么情况下会阻塞加载?
css后面跟着嵌入js的时候,会阻塞后面资源的下载,而把嵌入js放置在css前面就不会阻塞资源加载了。
原因:
因为浏览器会维持html中css和js的顺序,样式表必须在嵌入js前先加载、解析完。而嵌入js又会阻塞后面的资源加载,所以就会出现css阻塞下载的情况
嵌入js应该放在什么位置?
1.放置在底部,虽然放在底部会阻塞所有呈现,但不会阻塞资源下载
2.放在head,放在css前面
3.使用defer
4.嵌入js中不要调用运行时间较长的函数,如果要调用,可以使用setTimeout来调用
js无阻塞加载方式?
- 将脚本放在底部:script标签放在
</body>
前 - 非阻塞脚本:等页面加载完后,再加载js。也就是在onload事件下载js
- 1.defer属性/async属性
- 2.动态创建dom方式(创建script,插入文档,onload事件回调触发)
eval是做什么的?
功能是将对应的字符串解析成js代码并执行。
应该避免使用eval,不安全,耗性能(2次,一次解析成js代码,一次执行)
事件冒泡和事件捕获?
事件流描述的是从页面接收事件的顺序。
IE是冒泡事件流
Firefox是捕获事件流
- 事件冒泡:即事件从具体的元素到不具体的元素,从内向外传递事件
- 事件捕获:即事件从不具体的元素到具体的元素
事件冒泡和事件捕获是两个相反的过程
1 |
|
文档结构:document > html > body > div > h5
addEventListener的第三个参数为false,所以页面是在冒泡阶段处理绑定事件
1.点击文字welcome,触发obj1的点击事件,弹出hello
2.点击文字hello,触发obj2的点击事件,弹出world > hello
3.点击world时,触发obj1的点击事件,弹出hello
- 事件代理机制:
我们想要在点击每个h5标签时,弹出对应的innerHTML 。常规做法是遍历每个h5,然后在每个h5上绑定一个点击事件,这种做法在h5较少的时候可以使用,但如果有一万个h5,那就会导致性能降低。这时就需要事件代理出场了。
1 | obj1.addEventListener('click',function(e){ |
由于事件冒泡机制,点击了h5后会冒泡到div,此时就会触发绑定在div上的点击事件,再利用target找到事件实际发生的元素,就可以达到预期的效果
采用事件代理,为页面所有a标签绑定click事件
1 | document.addEvenetListenser('click',function(e){ |
问题:若a标签里面仍有span、img等其他元素,上述代码中,单击span、img等其他元素不能触发click事件。
原因:单击span、img等其他元素时,e.target指向的是触发click事件的元素(span、img等其他元素),而不是a标签
解决方法:从触发click事件的元素开始,逐级向上查找,直到找到a标签为止。
1 | document.addEventListener('click',function(e){ |
阻止事件冒泡:e.stopPropagation(),ie旧方法e.cancelBubble = true
如何获取UA
1 | <script> |
js操作和设置cookie
1 | //创建cookie |
tcp三次握手
为了准确无误将数据送达目标处,TCP协议采取了三次握手协议。
用tcp协议将数据包送出去后,tcp不会对发送后的情况置之不理,它一定向对方确认是否收到。
- 1.发送端首先发送带SYN标志的数据给对方。
- 2.接收方收到后回传一个SYN/ACK标志的数据包以示传达确认信息。
- 3.最后,发送端再回传一个带ACK标志的字段,代表握手结束
若在握手过程中某个阶段被打断,TCP会再次以相同的顺序发送数据包。
对promise的理解
promise有四种状态:
- 1.pending:初始状态,非fullfilled或rejected
- 2.fullfilled: 成功的状态
- 3.rejected: 失败的状态
- 4:settled:promise已被fullfilled或rejected,且不是pending
另外,fullfilled和rejected合称settled
1 | var promise = new Promise(function(resolve, reject) { |
Promise 实例拥有 then 方法(具有 then 方法的对象,通常被称为 thenable)。它的使用方法如下:
1 | promise.then(onFulfilled, onRejected) |
接收两个函数作为参数,一个在 fulfilled 的时候被调用,一个在 rejected 的时候被调用,接收参数就是 future,onFulfilled 对应 resolve, onRejected 对应 reject
谈谈性能优化问题
代码层面:避免使用css表达式,避免使用高级选择器,通配选择器。
缓存利用:缓存Ajax,使用CDN,使用外部js和css文件以便缓存,添加Expires头,服务端配置Etag,减少DNS查找等
请求数量:合并样式和脚本,使用css图片精灵,初始首屏之外的图片资源按需加载,静态资源延迟加载。
请求带宽:压缩文件,开启GZIP
什么是Etag?
浏览器下载组件的时候,会将它们存储到浏览器缓存中。如果需要再次获取相同的组件,浏览器将检查组件的缓存时间,假如已经过期,那么浏览器将发送一个条件GET请求到服务器,服务器判断缓存还有效,则发送一个304响应
告诉浏览器可以重用缓存组件
那么服务器是根据什么判断缓存是否还有效呢?答案有两种方式,一种是前面提到的ETag,另一种是根据Last-Modified
栈和队列的区别?
栈的插入和删除操作都是在一端进行的,而队列的操作却是在两端进行的。
队列先进先出,栈先进后出。
栈只允许在表尾一端进行插入和删除,而队列只允许在表尾一端进行插入,在表头一端进行删除
栈和堆的区别?
栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。
堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。
堆(数据结构):堆可以被看成是一棵树,如:堆排序;
栈(数据结构):一种先进后出的数据结构。
关于Http 2.0 你知道多少?
HTTP/2引入了“服务端推(serverpush)”的概念,它允许服务端在客户端需要数据之前就主动地将数据发送到客户端缓存中,从而提高性能。
HTTP/2提供更多的加密支持
HTTP/2使用多路技术,允许多个消息在一个连接上同时交差。
它增加了头压缩(header compression),因此即使非常小的请求,其请求和响应的header都只会占用很小比例的带宽。