高频面试题
一、js部分
1.事件循环(event loop)
众所周知,js的任务分为同步任务和异步任务,而异步任务又分为宏任务和微任务。那么,什么是宏任务什么是微任务呢?
宏任务:DOM 渲染后触发,如 setTimeout、setInterval 、DOM 事件 、script 。
微任务:DOM 渲染前触发,如 Promise.then 、MutationObserver、Node 环境下的 process.nextTick 。
js的执行过程从上到下,单线程执行。遇到同步任务会直接执行,执行完毕后再去执行下一行代码。而遇到异步任务会将其放置在任务队列中,当所有的同步任务执行完毕再去执行异步任务。
而异步任务中又分为宏任务和微任务,它们之间的执行顺序是:先去执行微任务,当所有的微任务执行完毕后,再去执行第一个宏任务。当这个宏任务执行完毕后,再去微任务队列里寻找有没有新的微任务,当所有新的微任务执行完毕后,再去执行第二个宏任务,然后如此往复。这种循环执行任务的机制就被称为事件循环。
2.数组去重
众所周知,数组去重大致分为三种方法:自己遍历数组去重,new Set去重,第三方包去重
①自己遍历(原理都是两层遍历)
const arr = [1,2,2,3,4,3,5]
const newArr = []
arr.filter(item => {
// 如果item在newArr里不存在,就添加进去
if(!newArr.includes(item)) {
newArr.push(item)
}
})
console.log(newArr) // [1,2,3,4,5]
②set去重
const arr = [1,2,2,3,4,3,5]
const newArr = [...new Set(arr)] // [1,2,3,4,5]
tips:不能对对象数组去重,因为set保存的地址,而每个对象的地址是不一致的
③通过lodash第三方包去重
// lodash中存在uniq方法,用于普通数组的去重
import {uniq} from 'lodash';
const arr = [1,2,2,3,4,3,5]
const newArr = uniq(arr) // [1,2,3,4,5]
// uniqBy用于对对象数组去重
import {uniqBy} from 'lodash';
const objArr = [{id:1},{id:1},{id:2}]
// uniqBy(要去重的数组,去重的参照)
const newArr = uniqBy(objArr,'id')
3.服务端渲染
服务端渲染,也就是ssr(server side render),与之相对的就是客户端渲染。那么,什么是服务端渲染呢?
服务端渲染指的就是由服务端直接返回完整的html结构,再发送到浏览器进行渲染。
客户端渲染指的是我们平时渲染的过程, 由客户端返回JS和JSON文件完成页面和数据的拼接,生成DOM结构再交由浏览器渲染成页面的过程
服务端渲染优点: 页面渲染速度快 ,利于SEO;缺点:不利于前后端分离,开发效率低
4.跨域问题
为什么会出现跨域问题呢?因为浏览器有一个同源策略, 同源策略会阻止一个域的javascrip脚本和另一个域的内容进行交互 。同源是指协议、域名、端口三者完全相同,不同源则为跨域
解决跨域大致分为三种方法:①CORS ②JSONP ③代理
CORS:这种方式是后台去处理,前端不需要做任何操作
JSONP: 最早解决跨域的方案,利用script标签的src属性可以跨域的原理实现。 这种方法缺点是只能发送get请求,并且也有着安全性的问题,容易遭受xss恶意注入代码
服务器代理:这种方式的原理是服务器和服务器之间并不受到浏览器同源策略的影响。
①webpack本地代理 :可以通过在webpack的devServer配置项的proxy属性里进行代理。
② Nginx反向代理 :需要搭建一个中转Nginx服务器,用于转发请求。具体操作和webpack本地代理类似,也是修改配置实现跨域
5.前端一次性渲染大量数据
在有些场景我们可能会遇到要一次渲染大量数据,但是当我们将数据渲染出来时会发现浏览器响应很慢甚至有可能崩掉。这时候要怎么解决呢?
这时我们可以通过虚拟DOM+虚拟列表来解决
虚拟DOM是一个js对象,用于描述dom节点。与真实dom不同的是,虚拟dom只保留了关键的信息,它比真实dom的少了非常多属性。这样在渲染界面时,它可以极大地提高渲染效率
虚拟列表其实就是一种按需显示的实现,即只对可视区域进行渲染,对非可见区域或不必要区域的数据不渲染或者部分渲染。它的原理就是,监听页面的滚动事件。当我们进行页面滚动时,它会更新我们视口区域的dom,在视口区域之外的旧dom会被删除。这样就保持永远只渲染一定量的dom节点,你要看哪部分我就更新哪一个部分给你,不需要的dom节点就删除。