前端面试集锦
-
vue生命周期
- 创建期间的生命周期函数:
+ beforeCreate:实例刚在内存中被创建出来,此时,还没有初始化好 data 和 methods 属性
+ created:实例已经在内存中创建OK,此时 data 和 methods 已经创建OK,此时还没有开始 编译模板
+ beforeMount:此时已经完成了模板的编译,但是还没有挂载到页面中
+ mounted:此时,已经将编译好的模板,挂载到了页面指定的容器中显示
- 运行期间的生命周期函数:
+ beforeUpdate:状态更新之前执行此函数, 此时 data 中的状态值是最新的,但是界面上显示的 数据还是旧的,因为此时还没有开始重新渲染DOM节点
+ updated:实例更新完毕之后调用此函数,此时 data 中的状态值 和 界面上显示的数据,都已经完成了更新,界面已经被重新渲染好了!
- 销毁期间的生命周期函数:
+ beforeDestroy:实例销毁之前调用。在这一步,实例仍然完全可用。
+ destroyed:Vue 实例销毁后调用。调用后,Vue 实例指示的所有东西都会解绑定,所有的事件监听器会被移除,所有的子实例也会被销毁 -
vue优缺点
优点
- 组件化开发
- 单页面路由
- 丰富的Api方法
- 双向数据绑定
- 单向数据流
- 易于结合其他第三库
- 用户体验好,快,内容的改变不需要重新加载整个页面
缺点
- 生态系统不够完善
- 可扩展性稍差
- 不利于seo
- 初次加载时耗时多
-
props
父子组件之间的通信就是 props down,events up,父组件通过 属性props向下传递数据给子组件,子组件通过 事件events 给父组件发送消息。
比如,子组件需要某个数据,就在内部定义一个prop属性,然后父组件就像给html元素指定特性值一样,把自己的data属性传递给子组件的这个属性。
而当子组件内部发生了什么事情的时候,就通过自定义事件来把这个事情涉及到的数据暴露出来,供父组件处理。 -
flex布局
-
css
-
css盒子模型
概念:盒子模型,顾名思义,盒子就是用来装东西的,它装的东西就是HTML元素的内容。或者说,每一个可见的 HTML 元素都是一个盒子,下面所说的盒子都等同于 HTML 元素。
组成:一个盒子由外到内可以分成四个部分:margin(外边距)、border(边框)、padding(内边距)、content(内容)。会发现margin、border、padding是CSS属性,因此可以通过这三个属性来控制盒子的这三个部分。而content则是HTML元素的内容。
盒子大小:
width
和height
属性设置的是盒子的宽度和高度。盒子的宽度和高度的计算方式由box-sizing属性控制。box-sizing属性值
content-box:默认值,width和height属性分别应用到元素的内容框。在宽度和高度之外绘制元素的内边距、边框、外边距。
border-box:为元素设定的width和height属性决定了元素的边框盒。就是说,为元素指定的任何内边距和边框都将在已设定的宽度和高度内进行绘制。通过从已设定的宽度和高度分别减去 边框 和 内边距 才能得到内容的宽度和高度。
inherit:规定应从父元素继承box-sizing属性的值。
当
box-sizing:content-box
时,这种盒子模型称为标准盒子模型,当box-sizing: border-box
时,这种盒子模型称为IE盒子模型。盒子成分:
margin是完全透明的,只可以设置边距。
/*margin属性后跟四个值,第一个值设置上边距,第二个是设置右边距,第三个值设置下边距,第四个值设置左边距*/ margin: 10px 20px 30px 40px; /*下面样式与上面的样式等价*/ margin-top: 10px; margin-right: 20px; margin-bottom: 30px; margin-left: 40px;
padding不是只能完全透明的,可以设置背景颜色和图片。
border可以设置成可见的,样式多样的。
-
css加载优先级
类别
-
行内样式:即
style = "font-size: 12px";
-
id选择器:即
#thisId {font-size: 12px;}
-
class选择器:即
.thisClass {font-size: 12px;}
-
元素选择器:即
p {font-size: 12px;}
加载顺序一般是:(外部样式)External style sheet <(内部样式)Internal style sheet <(内联样式)Inline style
有种特殊情况: 就是如果外部样式放在内部样式的后面,则外部样式将覆盖内部样式。优先级
内联样式 > id选择器样式 > 类选择器样式 > 元素选择器样式;
如果比较后权重相同,那么后者覆盖前者,后渲染的胜出;
!important 表示强制应用该样式,例如:
button{ width: 150px !important;}
,与以上的选择器相遇时,强制使用此样式;CSS选择器的使用,应该尽量避免使用 !important 和 内联样式;id通常也是与class区分开使用,前者多用于JS中的结点定位,后者多用于CSS选择器。
-
-
-
存储方式
-
本地存储localStorage
-
本地存储sessionStorage
-
cookie
cookie,localStorage,sessionStorage区别
相同:在本地(浏览器端)存储数据。
不同:
- localStorage只要在相同的协议、相同的主机名、相同的端口下,就能读取\修改到同一份localStorage数据。
- sessionStorage比localStorage更严苛一点,除了协议、主机名、端口外,还要求在同一窗口(也就是浏览器的标签页)下。
- localStorage是永久存储,除非手动删除。
- sessionStorage当会话结束(当前页面关闭的时候,自动销毁)
- cookie的数据会在每一次发送http请求的时候,同时发送给服务器而localStorage、sessionStorage不会。
-
-
块级元素与行内元素
区别:
行内元素:
- 与其他行内元素并排
- 不能设置宽高,默认的宽度就是文字的宽度
块级元素:
- 霸占一行,不能与其他任何元素并列。
- 能接受宽高,如果不设置宽度,那么宽度将默认变为父级的100%。
分类:
文本级标签:p , span , a , b , i , u , em
容器级标签:div , h系列 , li , dt ,dd
行内元素:除了p之外,所有的文本级标签,都是行内元素。p是个文本级标签,但是是个块级元素。
块级元素:所有的容器级标签,都是块级元素,以及p标签。
-
跨域问题
-
HTML5新标签
video 表示一段视频并提供播放的用户界面
audio 表示音频
canvas 表示位图区域
source 为video和audio提供数据源
track 为video和audio指定字母
svg 定义矢量图
code 代码段
figure 和文档有关的图例
figcaption 图例的说明
main
time 日期和时间值
mark 高亮的引用文字
datalist 提供给其他控件的预定义选项
keygen 秘钥对生成器控件
output 计算值
progress 进度条
menu 菜单
embed 嵌入的外部资源
menuitem 用户可点击的菜单项
menu 菜单
template
section
nav
aside
article
footer
header
-
盒子水平垂直居中
.parent{ display: flex; justify-content: center; align-items: center; } /*如同flex布局的第一部分一样这里也可以对子元素进行下面的设置:同时删除上面的除去display外的其他属性*/ /* .child{ margin:auto; } */
-
前后端分离原因以及优点
原因:
2.1 现有开发模式的适用场景
玉伯提到的几种开发模式,各有各的适用场景,没有哪一种完全取代另外一种。
-
比如后端为主的MVC,做一些同步展现的业务效率很高,但是遇到同步异步结合的页面,与后端开发沟通起来就会比较麻烦。
-
Ajax为主SPA型开发模式,比较适合开发APP类型的场景,但是只适合做APP,因为SEO等问题不好解决,对于很多类型的系统,这种开发方式也过重。
2.2 前后端职责不清
在业务逻辑复杂的系统里,我们最怕维护前后端混杂在一起的代码,因为没有约束,M-V-C每一层都可能出现别的层的代码,日积月累,完全没有维护性可言。
虽然前后端分离没办法完全解决这种问题,但是可以大大缓解。因为从物理层次上保证了你不可能这么做。2.3 开发效率问题
淘宝的Web基本上都是基于MVC框架webx,架构决定了前端只能依赖后端。
所以我们的开发模式依然是,前端写好静态demo,后端翻译成VM模版,这种模式的问题就不说了,被吐槽了很久。
直接基于后端环境开发也很痛苦,配置安装使用都很麻烦。为了解决这个问题,我们发明了各种工具,比如 VMarket,但是前端还是要写VM,而且依赖后端数据,效率依然不高。
另外,后端也没法摆脱对展现的强关注,从而专心于业务逻辑层的开发。2.4 对前端发挥的局限
性能优化如果只在前端做空间非常有限,于是我们经常需要后端合作才能碰撞出火花,但由于后端框架限制,我们很难使用Comet、Bigpipe等技术方案来优化性能。
优点:
- 最大的好处就是前端JS可以做很大部分的数据处理工作,对服务器的压力减小到最小
- 后台错误不会直接反映到前台,错误接秒较为友好
- 由于后台是很难去探知前台页面的分布情况,而这又是JS的强项,而JS又是无法独立和服务器进行通讯的。所以单单用后台去控制整体页面,又或者只靠JS完成效果,都会难度加大,前后台各尽其职可以最大程度的减少开发难度。
-
-
webGL
可参考webgl
-
webSocket
可参考WebSocket 教程
-
响应式开发
Ethan Marcotte在2010年5月份提出的一个概念,旨在让一个网站同时兼容多种设备,而不是为不同设备定制不同的版本。如果把我们的网站看做一个程序的话,响应式设计要求网站能提供更多用户端可选的参数,让用户拥有更多的控制权。
-
页面基本布局
-
border-box与content-box区别
content-box
padding和border不被包含在定义的width和height之内。对象的实际宽度等于设置的width值和border、padding之和;
即 ( Element width = width + border + padding ),属性表现为标准模式下的盒模型。
border-box
padding和border被包含在定义的width和height之内。对象的实际宽度就等于设置的width值,即使定义有border和padding也不会改变对象的实际宽度;
即 ( Element width = width ),此属性表现为怪异模式下的盒模型。
举个例子,我们在业务中遇到一个问题,我的商品详情页的一个盒子是高度自适应的,为146px,但是在ie8浏览器上显示为146.8px,如何解决,如果对盒子设置
height:146px;
则会出现被撑高的情况,因为box-sizing默认为content-box,你给元素设置宽高,只是给元素内容设置宽高,你元素的总高度是heigtht + border + padding
所以就会出现撑高,解决方法就是给当前的盒子设置box-sizing: border-box
这样你设置高度为146px时,会默然将元素内容的高度进行相应减少来保证整体高度为146px,这个最大的好处就是你这个盒子有好几个,而且有不同的padding和border值,解决这个的最好的方法就是给盒子设置border-box
-
页面隐藏元素的区别(display:none、opacity:0、visibility:hidden、pointer-event:none)
display: none
DOM
结构: 浏览器不会渲染display:none
的元素, 并且不占据页面空间- 事件监听: 无法对元素进行事件监听
- 继承: 不会被子元素继承(子元素设置
display: block
不会显示) - 改动: 改动属性值会引起页面的重排和重绘
- 过渡: 无法设置过渡效果
transition: display
无效
visibility: hidden
- 不会被渲染,但是会占据页面空间
- 无法对元素设置事件监听
- 可以继承,子元素设置非
visibility:hidden
可以显示 - 改动属性只会引起页面重绘
transition:visibility
会立即显示,hidden有过渡效果
opacity: 0
- 元素被隐藏, 会占据页面空间
- 可以设置事件监听
- 可以继承,
子元素设置opacity可以显示
- 不会重绘也不会重排
transition
:opacity
可以实现显示隐藏的过渡效果opacity
会触发硬件加速
pointer-event:none
-
pointer-events: none; 可以让某个元素实现类似于海市蜃楼的效果,具体理解为,你可以看的到某个元素,但是你无法摸的着。
-
display:none; 是你摸不着,但是你也看不见。pointer-events: none;摸不着,但是看得见。如果把某个元素再加上opacity:0;则可以很容易实现类似display:none;的效果(摸不着,看不见)。
-
如果为a标签设置了“pointer-events: none ”,点击a标签,不会跳转到链接地址,而且也没有悬浮样式,但是通过tab键可以选中连接进行跳转,可以把href去掉,这样就不能选中了
我写了一个div(X)和一个超链接(链接百度),我通过定位把他们放到了同一个地方,div在上,超链接在下,现在点击超链接是没有反应的,因为上面还有层div,超链接被遮挡住了
,如果为div设置了“pointer-events: none ”,再点击超链接,页面就进行跳转了,相当于div只是一个虚设的东西,如同海市蜃楼,任何事件都可以轻易从它身上穿过去!
-
js变量声明方式及区别
var
声明全局变量,换句话理解就是,声明在for循环中的变量,跳出for循环同样可以使用。
for(var i=0;i<=1000;i++){ var sum=0; sum+=i; } alert(sum);
声明在for循环内部的sum,跳出for循环一样可以使用,不会报错正常弹出结果
let
声明块级变量,即局部变量。 在上面的例子中,跳出for循环,再使用sum变量就会报错
注意:必须声明'use strict'后才能使用let声明变量否则浏览并不能显示结果
const
用于声明常量,也具有块级作用域 const PI=3.14;