面经练习:点击进入
H5 新特性
语义化标签:header、footer、section、nav、aside、article
增强型表单:input 的多个 type
新增表单元素:datalist、keygen、output
新增表单属性:placehoder、required、min 和 max
音频视频:audio、video
canvas
地理定位
拖拽
本地存储:localStorage - 没有时间限制的数据存储;sessionStorage - 针对一个 session 的数据存储,当用户关闭浏览器窗口后,数据会被删除
新事件:onresize、ondrag、onscroll、onmousewheel、onerror、onplay、onpause
WebSocket:单个 TCP 连接上进行全双工通讯的协议
CSS3 新特性
选择器
背景和边框
文本效果
2D/3D 转换
动画、过渡
多列布局
用户界面
HTTP1.0和HTTP2.0的区别
HTTP/2采用二进制格式而非文本格式
HTTP/2是完全多路复用的,而非有序并阻塞的——只需一个连接即可实现并行
使用报头压缩,HTTP/2降低了开销
HTTP/2让服务器可以将响应主动“推送”到客户端缓存中
HTTP和HTTPS的区别
https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。
js
1.判断数据类型的方法
//方法1:typeof 一元表达式,返回这个表达式的数据类型的字符串(全小写字母)
typeof "" //"string"
//方法2:A instanceof B,A是否为B的实例
{} instanceof Object //true
//方法3:
''.constructor == String //true
//方法4:Object对象,直接调用toString()就能返回[object Object],
//而对于其他对象,则需要通过call、apply来调用才能返回正确的类型信息
Object.prototype.toString({a: 1}) //"[object, Object]"
Object.prototype.toString().call(true) //"[object Boolean]"
2.两个数值相互交换
//方法1:引入第三变量
var a = 1, b = 2, tmp;
tmp = a;
a = b;
b = tmp;
//方法2:异或运算
var a = 1, //0001
b = 2; //0010
a = a ^ b; //a:0011 b:0010
b = a ^ b; //a:0011 b:0001
a = a ^ b; //a:0010 b:0001
//方法3:ES6的解构
let a = 1, b = 2;
[a, b] = [b, a];
//方法4:利用数组特性
var a = 1, b = 2;
a = [a, b];
b = a[0];
a = a[1];
3.for、forEach、map、for…of与for…in的区别
遍历数组
var arr = ["星期一","星期二","星期三"]
for:常规语句遍历,可循环数字,字符串,数组
for (var i=0; i<arr.length; i++){
console.log(i)
console.log(arr[i])
}
forEach:不能使用break、continue和return语句
arr.forEach((item, i) => {
console.log(item)
})
map:有返回值,返回一个结果数组
var a = arr.map((item, i) => {
console.log(item)
return item === '星期二'
})
console.log(a)
for...of:遍历数组的值
for (var item of arr){
console.log(item)
}
遍历数组、对象
for...in:遍历时,原型链上的所有属性都将被访问
//数组
var arr = ["星期一","星期二","星期三"];
Array.prototype.something = ["放假","休息咯"];
for (var i in arr){
if(arr.hasOwnProperty(i)){ //检测一个属性是存在于实例中,还是存在于原型中
console.log(arr[i])
}
}
//对象
var obj = {guangzhou: '广州', shanghai: '上海', beijing: '北京'}
Object.prototype.something2={shenzhen:'深圳'}
for (var i in obj){
if(obj.hasOwnProperty(i)){
console.log(obj[i])
}
}
4.事件委托
利用冒泡的原理,把事件加到父级上,触发执行效果。
好处:
1.提高性能;
2.新添加的元素还会有之前的事件。
例子:需要触发每个li来改变他们的背景颜色
window.onload = function(){
var oUl = document.getElementById("ul");
var aLi = oUl.getElementsByTagName("li");
var oBtn = document.getElementById("btn");
var iNow = 4;
//多个li用for循环的话就比较影响性能
oUl.onmouseover = function(ev){
var target = ev.target || window.event.srcElement; //获取事件源
//alert(target.innerHTML);
if(target.nodeName.toLowerCase() == "li"){
target.style.background = "red";
}
}
oUl.onmouseout = function(ev){
var target = ev.target || window.event.srcElement;
if(target.nodeName.toLowerCase() == "li"){
target.style.background = "";
}
}
//点击button动态添加li
oBtn.onclick = function(){
iNow ++;
var oLi = document.createElement("li");
oLi.innerHTML = 1111 *iNow;
oUl.appendChild(oLi);
}
}
5.token失效,记住当前页面url
sessionStorage.setItem('redirectUrl', that.$router.currentRoute.fullPath)
if (sessionStorage.length > 0 && sessionStorage.getItem('redirectUrl') != null) {
let _url = sessionStorage.getItem('redirectUrl')
sessionStorage.removeItem('redirectUrl')
that.$router.push({
path: _url
})
}
else {
that.$router.push({
path: '/'
})
}
6.浅拷贝和深拷贝
//被赋值的变量改变是否会影响原始值
//浅拷贝:影响
this.dataB = this.dataA;
//深拷贝:不影响
this.dataB = JSON.parse(JSON.stringify(this.dataA));
7.判断对象是否为空的方法
JSON.stringify(XXX) == '{}' //方法1
Object.keys(XXX).length == 0 //方法2
8.ajax请求的原理
通过XMLHttpRequest对象来向服务器发送异步请求,从服务器获取数据。
然后用JavaScript来操作DOM而无刷新更新页面。
1、创建XMLHttpRequest对象
//var xhr = new XMLHttpRequest();
//var xhr = new ActiveXObjectA("Microsoft.XMLHTTP"); //IE6 的兼容写法
//兼容
var xhr = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject("Microsoft.XMLHTTP");
2、与服务器建立连接
xhr.open("GET","URL",true);
//post需要设置请求头 get不用
xhr.setRequestHeader("content-type","application/x-www-from-urlencoded")
3、发送请求 post 请求的时候需要将数据放在send 中
xhr.send();
4、接受返回值
/*
onreadystatechange: 监听 ajax 和 服务端的状态
xhr.readyState ajax的状态
0:(未初始化)还没有调用send()方法
1:(载入)已调用send()方法,正在发送请求
2:(载入完成)send()方法执行完成,已经接收到全部响应内容
3:(交互)正在解析响应内容
4:(完成)响应内容解析完成,可以在客户端调用了
xhr.status 服务端的状态
*/
xhr.onreadystatechange = function(){
if(xhr.readyState === 4 && xhr.status === 200){
//数据通过xhr.responseText进行获取
console.log(xhr.responseText)
}
}
9.fetch和xhr的区别
1. fetch的语法简洁,更语义化
2. 基于promise,支持async/await
3. 同构方便,使用isomorphic-fetch
Fetch的缺点:
1. fetch只对网络错误报错,http状态码错误不报错
2. fetch不支持abort,无法终止
3. fetch不支持超时控制,使用setTimeout和Promise.reject实现的超时控制不能阻止请求过程继续在后台运行,造成了流量的浪费
4. fetch没有原生检测请求进度的方式,XHR可以
5. 默认情况下fetch不发送cookie,除非手动配置
Vue
1.对vue3.0的了解
-
性能比vue2.x快1.2~2倍
【diff算法】根据DOM的的内容会不会发生内容变化,添加静态标记
【静态提升】对于不参与更新的元素,会做静态提升,只被创建一次,在渲染时直接复用
【事件侦听缓存】onclick为动态绑定,所以每次都会追踪它的变化,但是因为是同一函数,没有必要追踪变化,直接缓存复用 -
支持tree-shaking,按需编译,体积比vue2.x更小
在vue3.0中创建vue项目 除了vue-cli,webpack外还有 一种创建方法:Vite
【Vite实现原理】利用ES6的import会发送请求去加载文件的特性,拦截这些请求,做一些预编译,省去webpack冗长的打包时间 -
支持组合API
setup()函数是组合API的入口函数
利用组合API进行函数式抽离,解决vue2.0业务分散的问题首先composition API(组合API)
和 Option API(vue2.0中的data和method)可以共用
composition API(组合API)本质就是把内容添加到Option API中进行使用 -
更好的支持TS(TypeScript)
-
更先进的组件
2.父组件和子组件的生命周期钩子执行顺序
不管是哪种情况,都一定是父组件等待子组件完成后,才会执行自己对应要完成的钩子
【渲染过程】
父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted
【更新过程】
父(子)组件更新影响子(父):父beforeUpdate -> 子beforeUpdate->子updated -> 父updated
父(子)组件更新不影响子(父):父beforeUpdate -> 父updated(子beforeUpdate -> 子updated)
【销毁过程】
父beforeDestroy -> 子beforeDestroy -> 子destroyed -> 父destroyed
3.axios
axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它本身具有以下特征:
从浏览器中创建 XMLHttpRequest
从 node.js 发出 http 请求
支持 Promise API
拦截请求和响应
转换请求和响应数据
取消请求
自动转换JSON数据
客户端支持防止 CSRF/XSRF