前端面试题
类型
HTML
1. HTML5有哪些新特性,怎么区分HTML和HTML5标签,怎么兼容HTML5标签
H5新特性:
语义化标签、表单新特性、视频(video)和音频(audio)、canvas画布、地理定位、为鼠标提供的拖放API、webworker、(重点)Storage、(重点)Websocket
区分HTML和H5:
- 文档类型声明上 HTML比较麻烦,而HTML5 :
<!DOCTYPE html>
- 在结构语义上:HTML没有体现结构语义化的标签,HTML5在语义上却有很大的优势。提供了一些新的html5标签
兼容h5标签
- 引用JS库:
<!–[if lt IE9]> <script src=”http://html5shiv.googlecode.com/svn/trunk/html5.js”></script> <![endif]–>
- 或者自己coding JS搞定
2. docment.write和innerHTML的区别
docment.write
是直接写入到页面的内容流,浏览器会自动调用document.open
, 会刷新页面;
innerHTML
是DOM页面元素的一个属性,代表该元素的html内容
3. 块级元素有哪些,行内元素有哪些,空元素有哪些
CSS 规范规定,每个元素都有 display 属性,确定该元素的类型,每个元素都有默认的 display 值,如 div 的 display 默认值为“block”,则为“块级”元素;span 默认 display 属性值为“inline”,是“行内”元素。
- 行内元素有:
a
b
span
img
input
select
strong(强调的语气)
- 块级元素有:
div
ul
ol
li
dl
dt
dd
h1
h2
h3
h4
p
空元素: - 常见:
br
hr
img
input
link
meta
- 不常见:
area
base
col
command
embed
4. cookie和session storage、local storage的区别
cookie
是网站为了标示用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)
cookie
数据始终在同源的 http
请求中携带(即使不需要),记会在浏览器和服务器间来回传递。
sessionStorage
和 localStorage
不会自动把数据发给服务器,仅在本地保存。
存储大小:
cookie
数据大小不能超过 4k。
sessionStorage
和 localStorage
虽然也有存储大小的限制,但比 cookie
大得多,可以达到 5M 或更大。
有效期(生命周期):
localStorage
: 存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;
sessionStorage
: 数据在当前浏览器窗口关闭后自动删除。
cookie
: 设置的 cookie
过期时间之前一直有效,即使窗口或浏览器关闭
CSS
1. css3有哪些新特性
CSS3的选择器
、@Font-face 特性
(加载字体样式,还能够加载服务器端的字体文件,让客户端显示客户端所没有安装的字体)、圆角(border-radius)
、阴影(Shadow)
、CSS3 的渐变效果
、动画
、canvas
等
2. canvas
<canvas> 是 HTML5 新增的元素,可用于通过使用JavaScript中的脚本来绘制图形
<canvas id="tutorial" width="150" height="150"></canvas>
3. 未知宽高下元素居中的方法
第一种方法:定位和transform
父元素:position: relative;
子元素: position: absolute;
left: 50%;
top: 50%;
transform: translate(-50%,-50%);
第二种方法:css3 flex布局 //使用flex布局,子元素必须是块级元素
父元素:display: flex;
justify-content: center;
align-items: center;
4. css有哪些属性不能被继承
不能被继承的属性:display、文本属性(vertical-align、text-shadow 等)、盒子模型的属性(width、height、margin 、border、padding 等)、背景属性(background)、定位属性(position)
可以被继承的属性:字体(font)、文本(color、line-height)、光标属性(cursor)等
JS
1. 浅拷贝和深度拷贝
浅拷贝只复制一层对象的属性,而深度拷贝则递归复制了所有层级
2.for、for in、for of、forEcah有什么区别
for 是循环,有判断条件 表达式
for in遍历对象
for...of相比于for...in更适合遍历数组
forEcah不能中断循环
3. 虚拟DOM为什么会提高性能
虚拟 dom 相当于在 js 和真实 dom 中间加了一个缓存,利用 dom diff
算法避免了没有必要的 dom 操作,从而提高性能。
用 JavaScript 对象结构表示 DOM 树的结构;
然后用这个树构建一个真正的 DOM 树,插到文档当中当状态变更的时候,重新构造一棵新的对象树。
然后用新的树和旧的树进行比较,记录两棵树差异把 2 所记录的差异应用到步骤 1 所构建的真正的 DOM 树上,视图就更新了。
4. http请求过程
HTTP协议即超文本传送协议(Hypertext Transfer Protocol ),是Web联网的基础,HTTP协议是建立在TCP协议之上的一种应用。
http协议:域名解析 --> 发起TCP的3次握手 --> 建立TCP连接后发起http请求 --> 服务器响应http请求,浏览器得到html代码 --> 浏览器解析html代码,并请求html代码中的资源(如js、css、图片等) --> 浏览器对页面进行渲染呈现给用户
5. http Header都包括哪些信息
HTTP请求头部信息:
- Accept:浏览器能够处理的内容类型
- Accept-Charset:浏览器能够显示的字符集
- Accept-Encoding:浏览器能够处理的压缩编码
- Accept-Language:浏览器当前设置的语言
- Connection:浏览器与服务器之间连接的类型
- Cookie:当前页面设置的任何Cookie
- Host:发出请求的页面所在的域
- Referer:发出请求的页面的URL
- User-Agent:浏览器的用户代理字符串
HTTP响应头部信息:
- Date:表示消息发送的时间,时间的描述格式由rfc822定义
- server:服务器名字
- Connection:浏览器与服务器之间连接的类型
- content-type:表示后面的文档属于什么MIME类型
- Cache-Control:控制HTTP缓存
6. http状态码
-
200 - 请求成功
-
301 - 资源(网页等)被永久转移到其它URL
-
404 - 请求的资源(网页等)不存在
-
500 - 内部服务器错误
HTTP状态码分类
- 1** - 服务器收到请求,需要请求者继续执行操作
- 2** - 请求成功,操作被成功接收并处理
- 3** - 重定向,需要进一步的操作以完成请求
- 4** - 客户端错误,请求包含语法错误或无法完成请求
- 5** - 服务器错误,服务器在处理请求的过程中发生了错误
7. 跨域
由于浏览器同源策略,凡是发送请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域
- 网络协议不同,如http协议访问https协议
- 端口不同,如80端口访问8080端口
- 域名不同,如qianduanblog.com访问baidu.com
- 子域名不同,如abc.qianduanblog.com访问def.qianduanblog.com
- 域名和域名对应ip,如www.a.com访问20.205.28.90
跨域请求资源
- CORS 【Cross-Origin Resource Sharing】(CORS支持所有类型的HTTP请求)
- jsonp (JSONP只支持GET请求,JSONP的优势在于支持老式浏览器)
- document.domain
- postMessage
8. 手写一个邮箱正则
/^(\w)+(\.\w+)*@(\w)+((\.\w+)+)$/
字符描述:
- ^ :匹配输入的开始位置
- \:将下一个字符标记为特殊字符或字面值
- :匹配前一个字符零次或几次
- :匹配前一个字符一次或多次
(pattern) 与模式匹配并记住匹配 - x|y:匹配 x 或 y
- [a-z] :表示某个范围内的字符。与指定区间内的任何字符匹配
- \w :与任何单词字符匹配,包括下划线
- {n,m} 最少匹配 n 次且最多匹配 m 次
- $ :匹配输入的结尾
9. 数组去重
//第一种方法
var arr = [2,3,4,4,5,2,3,6],
arr2 = [];
for(var i = 0;i< arr.length;i++){
if(arr2.indexOf(arr[i]) < 0){
arr2.push(arr[i]);
}
}
console.log(arr2); //[2, 3, 4, 5, 6]
//第二种方法
var res;
res=new Set( [2,3,4,4,5,2,3,6]);
res=Array.from(new Set( [2,3,4,4,5,2,3,6])); // Array.from,可以把类数组对象、可迭代对象转化为数组。
console.log(res) //es6 数组去重 [2, 3, 4, 5, 6]
10. 冒泡排序
//比较相邻的两个元素,如果前一个比后一个大,则交换位置
var arr= [1,10,2,20,19,35];
var len = arr.length;
for (var i = 0; i < len-1; i++) {
for (var j = 0; j < len - 1 - i; j++) {
// 相邻元素两两对比,元素交换,大的元素交换到后面
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
console.log(arr) // [1, 2, 10, 19, 20, 35]
11. 点击对应的li标签alert相应的index
<ul id='test'>
<li>123</li>
<li>123</li>
<li>123</li>
</ul>
var list=document.getElementById('test').children;//获取所有的li标签
for(var i=0;i<list.length;i++) {//遍历每一个li标签
function outer ( ) {
function inner ( ) {
alert(i);
}
return inner;
}
//给每一个li标签注册单击事件
list[i].onclick=outer();
}
12.promise用法和原理
promise的核心原理其实就是发布订阅模式,通过两个队列来缓存成功的回调(onResolve)和失败的回调(onReject)
Promise存在三个状态(state)pending、fulfilled、rejected,pending(等待态)为初始态,并可以转化为fulfilled(成功态)和rejected(失败态)
function Promise (executor) {
var self = this;//resolve和reject中的this指向不是promise实例,需要用self缓存
self.state = 'pending';
self.value = '';//缓存成功回调onfulfilled的参数
self.reson = '';//缓存失败回调onrejected的参数
self.onResolved = []; // 专门存放成功的回调onfulfilled的集合
self.onRejected = []; // 专门存放失败的回调onrejected的集合
function resolve (value) {
if(self.state==='padding'){
self.state==='resolved';
self.value=value;
self.onResolved.forEach(fn=>fn())
}
}
function reject (reason) {
self.state = 'rejected';
self.value = reason;
self.onRejected.forEach(fn=>fn())
}
try{
executor(resolve,reject)
}catch(e){
reject(e)
}
}
Promise.prototype.then=function (onfulfilled,onrejected) {
var self=this;
if(this.state==='resolved'){
onfulfilled(self.value)
}
if(this.state==='rejected'){
onrejected(self.value)
}
if(this.state==='padding'){
this.onResolved.push(function () {
onfulfilled(self.value)
})
}
}
13.Websocket通信原理
为web应用程序客户端和服务端之间(注意是客户端服务端)提供了一种全双工通信机制,建立在 TCP 协议之上,服务器端的实现比较容易
14.var、let、const 区别
var
是方法作用域,let
是块作用域- 变量声明之前就访问变量的话,
var
默认值undefined
,let
会直接提示ReferenceError
const
和let
的作用域是一致的,不同的是const
变量一旦被赋值,不能再改变了(变量本身可以再改变,但不可被再次赋值
const name = 'zhangsan' ;
name = 'lisi' //TypeError: Assignment to constant variable
const person = {
name = 'qwe';
}
person.name = 'asd'; //是可以改名字的
)
15.变量提升
a = 2;
var a;
console.log(a); //2
javascript
会将当前作用域的所有变量的声明提升到程序的顶部,因此上面的代码其实等价于以下代码
var a;
a = 2;
console.log(a);
如果
console.log(a);
var a = 2;
输出的是:undefined
因为 js会将变量的声明提升到顶部,可是赋值语句并不会提升
MVVM框架-Vue
1.MVC和MVVM的区别
- MVC的定义:MVC是Model-View- Controller的简写,即模型-视图-控制器
- Mvvm定义:MVVM是Model-View-ViewModel的简写,即模型-视图-视图模型。【模型】指的是后端传递的数据。【视图】指的是所看到的页面。【视图模型】mvvm模式的核心,它是连接view和model的桥梁
2. Vue和jq、Vue和react的区别
vue是数据驱动,通过数据来显示视图层而不是节点操作,jq是操作DOM,react是函数式
数据变换的感知:Vue是双向绑定的,react是单向数据流
3. Vue生命周期
beforeCreated
:生成$options
选项,并给实例添加生命周期相关属性。在实例初始化之后,在 数据观测(data observer) 和event/watcher 事件配置之前被调用,也就是说,data,watcher,methods都不存在这个阶段。但是有一个对象存在,那就是$route,因此此阶段就可以根据路由信息进行重定向等操作。created
:初始化与依赖注入相关的操作,会遍历传入methods的选项,初始化选项数据,从 o p t i o n s 获 取 数 据 选 项 ( v m . options获取数据选项(vm. options获取数据选项(vm.options.data),给数据添加‘观察器’对象并创建观察器,定义getter、setter存储器属性。在实例创建之后被调用,该阶段可以访问data,使用watcher、events、methods,也就是说 数据观测(data observer) 和event/watcher 事件配置 已完成。但是此时dom还没有被挂载。该阶段允许执行http请求操作。beforeMount
:将HTML解析生成AST节点,再根据AST节点动态生成渲染函数。相关render函数首次被调用(划重点)。mounted
:在挂载完成之后被调用,执行render函数生成虚拟dom,创建真实dom替换虚拟dom,并挂载到实例。可以操作dom,比如事件监听beforeUpdate
: v m . d a t a 更 新 之 后 , 虚 拟 d o m 重 新 渲 染 之 前 被 调 用 。 在 这 个 钩 子 可 以 修 改 vm.data更新之后,虚拟dom重新渲染之前被调用。在这个钩子可以修改 vm.data更新之后,虚拟dom重新渲染之前被调用。在这个钩子可以修改vm.data,并不会触发附加的冲渲染过程。updated
:虚拟dom重新渲染后调用,若再次修改$vm.data,会再次触发beforeUpdate、updated,进入死循环。beforeDestroy
:实例被销毁前调用,也就是说在这个阶段还是可以调用实例的destroyed
:实例被销毁后调用,所有的事件监听器已被移除,子实例被销毁
$destroy只是完全销毁一个实例。清理它与其它实例的连接,解绑它的全部指令及事件监听器
4.$route
和$router
的区别
$route
为当前router
跳转对象里面可以获取name
、path
、query
、params
等
$router
为VueRouter
实例,想要导航到不同URL,则使用$router.push
方法
返回上一个history
也是使用$router.go
方法
5.keep-alive
keep-alive
是Vue的内置组件,能在组件切换过程中将状态保留在内存中,防止重复渲染DOM
keep-alive
生命周期钩子函数:activated
、deactivated
6.Vue计算属性和watcher的区别
Vue计算属性:快速计算视图(View)中显示的属性,这些计算将被缓存,并且只在需要时更新
computed
用来监控自己定义的变量,该变量不在data里面声明,直接在computed里面定义,然后就可以在页面上进行双向数据绑定展示出结果或者用作其他处理;
computed
比较适合对多个变量或者对象进行处理后返回一个结果值,也就是数多个变量中的某一个值发生了变化则我们监控的这个值也就会发生变化watch
主要用于监控vue实例的变化,它监控的变量当然必须在data里面声明才可以,它可以监控一个变量,也可以是一个对象
7.Vue双向绑定原理
vue.js 是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。
8.vuex是什么,怎么使用
vue框架中状态管理。在main.js引入store,注入。新建了一个目录store,…… export
9. hash和history的区别
vue路由的核心是,更新视图但不重新请求页面,浏览器当前提供了以下两种支持
- hash —— 即地址栏 URL 中的 # 符号
比如这个 URL:http://www.xx/#/login
,hash 的值为#/login
。它的特点在于:hash 虽然出现在 URL 中,但不会被包括在 HTTP 请求中,对后端完全没有影响,因此改变 hash 不会重新加载页面。 - history ——可以 在url里放参数,还可以将数据存放在一个特定的对象中,利用了 HTML5 History Interface 中新增的 pushState() 和 replaceState() 方法。(需要特定浏览器支持)
这两个方法应用于浏览器的历史记录栈,在当前已有的 back、forward、go 的基础之上,它们提供了对历史记录进行修改的功能。只是当它们执行修改时,虽然改变了当前的 URL,但浏览器不会立即向后端发送请求。
10.SPA单页面的优缺点
优点:
- 体验好,不刷新,减少 请求 数据ajax异步获取 页面流程
- 前后端分离
- 减轻服务端压力
- 共用一套后端程序代码,设配多端
缺点:
- 首屏加载过慢 (解决方案:路由图片、懒加载、js按需加载、使用cdn、js放在body后边、压缩代码、移除console 、debugger;异步组件(const aa=resolve =>require([’…/xxx/xx’]),resolve)修改webpack配置 、添加登录专用的router配置 )
- SEO 不利于搜索引擎抓取 (解决方案:VUE SSR )
11.mutaion 和 action的区别
action可执行异步操作,业务中存在异步操作可用action
mutation只能执行同步操作,mutation是操作state唯一的途径