1.如何处理HTML5新标签的浏览器兼容问题
方法一:IE9以下的浏览器可以识别document.createElement()方法生成的标签
var e = "abbr, article, aside, audio, canvas, datalist, details, dialog, eventsource, figure, footer, header, hgroup, mark, menu, meter, nav, output, progress, section, time, video".split(', ');
var i= e.length;
while (i--){
document.createElement(e[i])
}
方法二:在页面的head部分使用html5shim框架
<!--[if lt IE 9]>
<script> src="http://html5shim.googlecode.com/svn/trunk/html5.js"</script>
<![endif]-->
2.用一个 div 模拟 textarea 的实现
给div添加contenteditable="true"
3.让一个元素垂直水平居中
4.浮动布局的优缺点?清除浮动有哪些方式
优点:使文字环绕在图片周围;拥有块元素属性可以设置宽高
缺点:浮动元素一旦脱离了文档流,就无法撑起父元素,会造成父级元素的高度塌陷
方式一:添加额外标签
<div class="parent">
//添加额外标签并且添加clear属性
<div style="clear:both"></div>
//也可以加一个br标签
</div>
方式二:父级添加overflow属性,或者设置高度
<div class="parent" style="overflow:hidden">//auto 也可以
//将父元素的overflow设置为hidden
<div class="f"></div>
</div>
方式三:建立伪类选择器清除浮动(推荐)
//在css中添加:after伪元素
.parent:after{
/* 设置添加子元素的内容是空 */
content: '';
/* 设置添加子元素为块级元素 */
display: block;
/* 设置添加的子元素的高度0 */
height: 0;
/* 设置添加子元素看不见 */
visibility: hidden;
/* 设置clear:both */
clear: both;
}
<div class="parent">
<div class="f"></div>
</div>
5.JS 原始数据类型有哪些?引用数据类型有哪些
原始数据类型:Undefined、Null、Boolean、String、Number、Symbol、BigInt 7种
引用数据类型:Object
6.null是对象吗?为什么?
null尽管使用typeOf打印出来是Object,但它不是对象。js最初使用版本中使用的事32位系统,为了性能考虑使用低位存储变量的类型信息,以000开头的表示对象,但null全是0,因为错误地判断为对象,这是一个bug。
7.get和post的区别
(1)url可见性:get可见,post不可见
(2)数据传输上:get通过拼接url传递参数,post通过body体传输参数
(3)缓存性:get请求可缓存,post不可缓存
(4)后退页面的反应:get请求页面后退无反应,post请求页面后退重新提交表单
(5)传输数据的大小:get传输数据大小一般不超过2-4kb,post传输受到浏览器和服务器限制
(6)安全性:表面上post参数地址栏看不到显得比较安全,但是 HTTP 在网络上是明文传输,只要抓包都能获取完整数据报文,所以想要安全传输,就必须使用加密使用HTTPS
8.canvas和svg的优缺点
(1)SVG 基于XML 描述 2D 图形,SVG DOM 中的每个元素都可以视为对象可用。
- 不依赖分辨率
- 支持事件处理器
- 最适合带有大型渲染区域的应用程序(比如谷歌地图)
- 复杂度高会减慢渲染速度(任何过度使用 DOM 的应用都不快)
- 不适合游戏应用
(2)Canvas 通过 JavaScript 来绘制 2D 图形,逐像素进行渲染。
- 依赖分辨率
- 不支持事件处理器
- 弱的文本渲染能力
- 能够以 .png 或 .jpg 格式保存结果图像
- 最适合图像密集型的游戏,其中的许多对象会被频繁重绘
9.MVC和MVVM的区别
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写。各部分之间单向通信。
MVVM是Model-View-ViewModel的简写,各部分之间是双向通信,mvvm 主要解决了 mvc 中大量的 DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。
10.$route和$router的区别
route是路由信息对象,里面主要包含路由的一些基本信息,包括name、meta、path、hash、query、params、fullPath、matched、redirectedFrom
router是VueRouter的实例,包含了一些路由的跳转方法,钩子函数等、
11.cookie和session的本质区别
(1)cookie和session都是基于键值对的字符串;
(2)俩个都是都由后端服务器生成的;
(3)cookie字符串保存在客户端浏览器中,session值保存在服务器中,session比cookie更安全。
(4)个人理解cookie相当于明文,而session类似于密文,是由后端服务器经过编码后的一段无序字符串。
(5)既然session是key-value格式的数据,则它的键session_id保存在cookie中的,值session_data保存在服务器,通过key来取到value,所以cookie也是实现Session跟踪的一种方式
12.组件化和模块化的区别
- 组件化:就是"基础库"或者“基础组件",意思是把代码重复的部分提炼出一个个组件供给功能使用。
使用:Dialog,各种自定义的UI控件、能在项目或者不同项目重复应用的代码等等。
目的:复用,解耦。
依赖:组件之间低依赖,比较独立。
架构定位:纵向分层(位于架构底层,被其他层所依赖)。
- 模块化:是"业务框架"或者“业务模块",也可以理解为“框架”,意思是把功能进行划分,将同一类型的代码整合在一起,所以模块的功能相对复杂,但都同属于一个业务。
使用:按照项目功能需求划分成不同类型的业务框架(例如:注册、登录、外卖、直播.....)
目的:隔离/封装 (高内聚)。
依赖:模块之间有依赖的关系,可通过路由器进行模块之间的耦合问题。
架构定位:横向分块(位于架构业务框架层)。
13.http和https的区别
- https协议需要到ca申请证书,一般免费证书较少,因而需要一定费用。
- http是超文本传输协议,信息是明文传输,https则是具有安全性的ssl加密传输协议。
- http和https使用的是完全不同的连接方式,用的端口也不一样,前者是80,后者是443。
- http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全
14.vue实现原理
vue2响应式原理主要就是通过数据劫持,依赖收集,派发更新的方式来实现的
- 数据劫持,vue2是通过Object.defineProperty来将对象的每一个属性转化成set,get。其中修改对象的属性时就会触发set,使用对象的属性时就会触发get
- 依赖收集。就是在渲染视图时 将watcher和具体的属性,通过发布订阅者模式管理,这样数据改变之后就能更精准的更新视图
- 派发更新:它就是通过dep来执行watcher的notify方法
缺点:
- 无法监听ES6的Set、Map变化
- 无法监听Class类型的数据
- 属性的新增和删除也无法监听
- 数组元素的增加和删除也无法监听
vue3的Proxy都能完成解决这些问题,但是兼容性不好,如果检测到浏览器是IE时(IE11都不支持Proxy),会自动优雅降级使用Object.defineProperty来监听数据。
底层原理面试回答:先通过Object.defineProperty的get和set拦截,每次修改数据set方法拦截到了,通过watcher观察者,watcher收录当前状态在页面中所有用到的地方,把所有相关联的组件代码进行更新,在更新过程中,会先创建一份新的虚拟dom节点,再对比老的虚拟dom节点,以最小的代价找出两者不同再更新到真实dom中。
15.Vue中computed、watch、methods三者区别
- methods(事件绑定)计算逻辑,可以不用return,没有缓存
- computed(重视结果)解决模板过重问题,必须有return,有缓存,异步
- watch(重视过程)监听一个值的改变,不用return,异步同步
16.浏览器有哪些进程和线程?
浏览器是一个多进程多线程的应用程序
浏览器内部工作极其复杂。为了避免相互影响,为了减少连环崩溃的几率,当启动浏览器后,它会自动启动多个进程。其中,最主要的进程有:
- 浏览器进程:主要负责界面显示、用户交互、子进程管理等。浏览器进程内部会启动多个线程处理不同的任务。
- 网络进程:负责加载网络资源。网络进程内部会启动多个线程来处理不同的网络任务。
- 渲染进程:渲染进程启动后,会开启一个渲染主线程,主线程负责执行 HTML、CSS、 JS 代码。默认情况下,浏览器会为每个标签⻚开启一个新的渲染进程,以保证不同的 标签⻚之间不相互影响。
17.渲染主线程的工作方式:事件循环
- 在最开始的时候,渲染主线程会进入一个无限循环
- 每一次循环会检查消息队列中是否有任务存在。如果有,就取出第一个任务执行,执行完一个后进入下一次循环;如果没有,则进入休眠状态。
- 其他所有线程(包括其他进程的线程)可以随时向消息队列添加任务。新任 务会加到消息队列的末尾。在添加新任务时,如果主线程是休眠状态,则会将其唤醒以继续循环拿取任务
整个过程,被称之为 事件循环(消息循环)
18.面试题:如何理解 JS 的异步?
- JS是一⻔单线程的语言,这是因为它运行在浏览器的渲染主线程中,而渲染主线程只有一个。而渲染主线程承担着诸多的工作,渲染⻚面、执行 JS 都在其中运行。
- 如果使用同步的方式,就极有可能导致主线程产生阻塞,从而导致消息队列 中的很多其他任务无法得到执行。
- 这样一来,一方面会导致繁忙的主线程白白的消耗时间,另一方面导致⻚面无法及时更新,给用户造成卡死现象,所以浏览器采用异步的方式来避免。
- 具体做法是当某些任务发生时,比如计时器、网络、事件监听,主线程将任务交给其他线程去处理,自身立即结束任务的执行,转而执行后续代码。
- 当其他线程完成时,将事先传递的回调函 数包装成任务,加入到消息队列的末尾排队,等待主线程调度执行。 在这种异步模式下,浏览器永不阻塞,从而最大限度的保证了单线程的流畅运行。
19.消息队列中任务有优先级吗
任务没有优先级,在消息队列中先进先出,但消息队列是有优先级的
根据 W3C 的最新解释:
- 每个任务都有一个任务类型,同一个类型的任务必须在一个队列,不同类型 的任务可以分属于不同的队列。
- 在一次事件循环中,浏览器可以根据实际情况从不同的队列中取出任务执行。
- 浏览器必须准备好一个微队列,微队列中的任务优先所有其他任务执行
在目前 chrome 的实现中,至少包含了下面的队列:
- 微队列:用户存放需要最快执行的任务,优先级「最高」
- 交互队列:用于存放用户操作后产生的事件处理任务,优先级「高」
- 延时队列:用于存放计时器到达后的回调任务,优先级「中」
添加任务到微队列的主要方式主要是使用 Promise
// 立即把一个函数添加到微队列 Promise.resolve().then(函数)
20.阐述一下 JS 的事件循环
事件循环又叫做消息循环,是浏览器渲染主线程的工作方式。
在 Chrome 的源码中,它开启一个不会结束的 for 循环,每次循环从消息 队列中取出第一个任务执行,而其他线程只需要在合适的时候将任务加入到 队列末尾即可。
过去把消息队列简单分为宏队列和微队列,这种说法目前已无法满足复杂的 浏览器环境,取而代之的是一种更加灵活多变的处理方式。
根据 W3C 官方的解释,每个任务有不同的类型,同类型的任务必须在同一个队列,不同的任务可以属于不同的队列。不同任务队列有不同的优先级, 在一次事件循环中,由浏览器自行决定取哪一个队列的任务。但浏览器必须 有一个微队列,微队列的任务一定具有最高的优先级,必须优先调度执行。
21.JS 中的计时器能做到精确计时吗
不可以,原因有以下四点:
- 计算机硬件没有原子钟,无法做到精确计时
- 操作系统的计时函数本身就有少量偏差,由于 JS 的计时器最终调用的是操作系统的函数,也就携带了这些偏差
- 按照 W3C 的标准,浏览器实现计时器时,如果嵌套层级超过 5 层,则会带有 4 毫秒的最少时间,这样在计时时间少于 4 毫秒时又带来了偏差
- 受事件循环的影响,计时器的回调函数只能在主线程空闲时运行,因此又带来了偏差