面经练习(十六)
1.promise的方法:
常见的 resolve reject all race
还有finally
不管promise最后的状态,在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数。
var promise = new Promise(function(resolve, reject) {
console.log("promise")
window.setTimeout(function(){
if (false){
resolve('huangbiao');
} else {
debugger
reject('error');
}
},1000)
}).then(function(){
console.log('success');
}).catch(function(){
console.log('catch');
}).finally(function(){
console.log('finally');
});
Promise.allSettled()方法返回一个promise,该promise在所有给定的promise已被解析或被拒绝后解析,并且每个对象都描述每个promise的结果。
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(1)
}, 50)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(22)
}, 10)
})
let p3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(3)
}, 20)
})
Promise.allSettled([p1, p2, p3]).then((res) => {
console.log(res);
})
2.微任务里面嵌套微任务如何执行
setTimeout(() => {
console.log(1);
})
new Promise((resolve, reject) => {
console.log(3);
resolve(4);
Promise.resolve(5).then((value) => {
console.log(value);
})
}).then((value) => {
console.log(value);
})
输出结果是 3541 微任务里面嵌套微任务时,里面的先执行
3.props,data,computed的加载顺序
可以看出来computed在data之后,所以不要在data中引用computed中的属性,只能得到undefined。
data可以调用前面的props,methods的属性
computed中可以调用props,methods,data中的属性
4.立即执行函数的作用
①不必为函数命名,避免了污染全局变量
②立即执行函数内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量
③封装变量
5.websocket原理以及和长连接的区别
其中有个101状态码 要注意
http和websocket的长连接区别
HTTP1.1通过使用Connection:keep-alive进行长连接,HTTP 1.1默认进行持久连接。在一次 TCP 连接中可以完成多个 HTTP 请求,但是对每个请求仍然要单独发 header,Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。这种长连接是一种“伪链接”
websocket的长连接,是一个真的全双工。长连接第一次tcp链路建立之后,后续数据可以双方都进行发送,不需要发送请求头。
keep-alive双方并没有建立正真的连接会话,服务端可以在任何一次请求完成后关闭。WebSocket 它本身就规定了是正真的、双工的长连接,两边都必须要维持住连接的状态。
6.link标签里面的nofollow
7.let和var的本质区别
1.首先举个例子:
var arr = []
for (var i = 0; i < 10; i++) {
arr[i] = function() {
console.log(i)
}
}
arr[2]() //10
console.log(i) //10
输入上述结果的原因是,var不会生成块级作用域 而且会变量提升
arr[i]这个函数 全局执行 输出window.i 就是10
我们想改变结果 把arr2输出结果变成期望的即 2
有两种方法:
①转换ES6使用let
var arr = []
for (let i = 0; i < 10; i++) {
arr[i] = function() {
console.log(i)
}
}
arr[2]() //2
console.log(i) //Uncaught ReferenceError: i is not defined
for循环中使用let声明变量i,这样每一层循环都重新声明了i,并绑定了当前循环的代码块,所以传入内存函数的额console.log(i)
也是当时的i的值,所以brr2执行时,变量i的值是2,在for循环外访问i会出错。
②使用闭包和立即执行函数
var arr = []
for (var i = 0; i < 10; i++) {
arr[i] = (function(i) {
return function() {
console.log(i)
}
})(i)
}
arr[2]() //2
console.log(i) //10
2.利用babel把let转换成var
"use strict";
var brr = [];
var loop = function loop(i) {
brr[i] = function () {
console.log(i);
};
};
for (var i = 0; i < 10; i++) {
loop(i);
}
brr[2]();
console.log(i);
8. var 和 setTimeout
for(var i=0;i<10;i++){
setTimeout(console.log(i),0);//0、1、2、3、4、5、6、7、8、9
}
for(var i=0;i<10;i++){
setTimeout(function(){ console.log(i);//连续的10个10 },0);
}
for(var i=0;i<10;i++){
setTimeout("console.log(i)",1000);//连续的10个10
}
第一个for循环每次遍历的i是全局变量,setTimeout里面没有回调函数,等于都是同步,你log输出就是0到9
第二个for循环,定时器里有回调函数。等于是一个异步任务,异步任务是只有等执行栈中同步任务执行完毕后才可以执行异步,因为js最大的特性就是单线程。当for循环同步任务结束后,此时i的值是10。for循环了10次,等于就是要调用10次这个回调函数,有10个异步任务在异步队伍列表里面等待,等执行栈同步任务执行完毕再执行,这10个任务就是log这个i变量。此时的i是10所以就是10个10
第三个和第二个一样,log加了引号类似于函数的调用方法;settimeout的传参需求,第一个如果是传递函数的调用方法的话,必须是以字符串的形式传参
9.keep-alive实现原理
1.使用场景:
①动态组件
<component v-bind:is="currentTabComponent"></component>
②vue-router中使用
包装 router-view
2.keep-alive各个参数的作用:
注意这里面的LRU算法
3.源码分析的话看转载的文章
9.HTML中a标签的target属性
10.利用对象的属性不能相同的特点进行数组去重
之前利用indexOf 和 ES6的set
还可以利用对象的属性不能相同的特点
1.创建一个新的数组存放结果
2.创建一个空对象
3.for循环时,每次取出一个元素与对象进行对比,如果这个元素不重复,则把它存放到结果数组中,同时把这个元素的内容作为对象的一个属性,并赋值为1,存入到第2步建立的对象中。
说明:至于如何对比,就是每次从原数组中取出一个元素,然后到对象中去访问这个属性,如果能访问到值,则说明重复。
function unique(arr){
var res = [];
var obj = {};
for(var i=0; i<arr.length; i++){
if( !obj[arr[i]] ){
obj[arr[i]] = 1;
res.push(arr[i]);
}
}
return res;
}
var arr = [1,2,2,3,5,3,6,5];
var res = unique(arr)
console.log(res );
11.CSS Modules
12.数组对象根据某个key的值去重
var myarry = [
{name: 'zhangsan',age :20},
{name:'lisi',age:13},
{name:'wangwu',age:18},
{name:'jake',age:17},
{name:'lisi',age:24} ]
// 传入数组和去重的key如name
function deweight (arr, key) {
let res = []
arr.forEach((item) => {
let list = []
res.forEach((resitem) => {
list.push(resitem[key])
})
if (list.indexOf(item[key]) === -1) {
res.push(item)
}
})
return res
}
var result = deweight(myarry,'name')
console.log(result)
13.webpack热更新原理:
WDS:webpack-dev-server(WDS)来实现自动刷新
14. vue自定义指令
注意 el 和 binding