1、说说你对Event Loop的理解?
Eventloop 是一种在编程语言中常用的编程模型,用于处理任务队列中的事件,它可以被用来处理各种任务,包括网络事件、文件读写、定时器、用户界面事件等
Eventloop 的工作原理是,它会按顺序处理在任务队列中的事件,当它处理完一个事件之后,就会检查队列中的下一个事件,并继续处理,直到队列中的事件全部处理完毕
Eventloop 同时会检查任务队列中是否有新的事件,如果有的话就会把它加入到队列虫,然后继续处理
Evcntloop 也可以用来处理异步任务,异步任务一般是指需要运行一段时问才能完成的任务。当一个异步任务被添加到任务队列中时,Eventloop 就会自动开始处理它,并在完成之后将处理结果返回给调用者
Eventloop 还可以用来处理多线程应用,它可以让多个线程之间共享任务队列,并共同处理任务,这样可以提高程序的执行效率。
Eventloop 的优势在于它能够有效地处理大量的事件,而不用担心处理的任务会超出系统的处理能力。此外,Eventloop 还可以提高程序的执行效率,因为它可以让任务在合适的时间执行,而不用担心系统会因为处理任务而受到阻碍
总之,Eventloop 是一种非常有用的编程模型,它可以帮助我们有效地处理大量的任务,提高程序的执行效率,提升编程的效率
2、说说你对BOM的理解,常见的BOM对象你了解哪些?
BOM是browser object model的缩写,简称浏览器对象模型 ,提供了独立于内容而与浏览器窗口进行交互的对象
- window对象 ,是JS的最顶层对象,其他的BOM对象都是window对象的属性
- document对象,文档对象
- location对象,浏览器当前URL信息
- navigator对象,浏览器本身信息
- screen对象,客户端屏幕信息
- history对象,浏览器访问历史信息
3、浏览器的内核都有哪些,什么区别?
目前市面上主打的浏览器大致分为下面几种:
- Tridend内核,如果不知道Tridend,那么你一定知道微软的IE吧,没错,它就是IE的核心引擎,从IE诞生到现在一直使用的就是Tridend内核,国内的80%以上的浏览器用的都是它,只是在IE上面再次做了包装和本地化而已,如果搜搜、搜狗、360、遨游、世界之窗;其中搜狗浏览器可以使用双引擎,该引擎只在windows平台下使用。
- Gecko内核,这个是火狐firefox御用内核,新版的火狐对其进行了内核升级,据说可以将速度提升2-5倍。
- Webkit内核,大家知道有苹果的和google的浏览器使用的是该内核,它的优点是快速解析javascript,也是这些浏览器打广告时经常用到的口号,国产的双引擎浏览器搜狗高速浏览器就是采用了该内核。
常用浏览器及其内核:
- 360浏览器:Chrome内核和IE内核。
- 百度浏览器:IE和Webkit双内核。
- QQ浏览器:Chromium内核+IE双内核。
- 猎豹浏览器:Trident和WebKit。
- 搜狗浏览器:chromium内核。
4、说说浏览器的渐进增强和优雅降级的区别?
- 渐进增强: 一开始就针对低版本浏览器进行构建页面,完成基本的功能,然后再针对高级浏览器进行效果、交互、追加功能达到更好的体验
- 优雅降级: 一开始针对一个高版本的浏览器构建页面,先完善所有的功能。然后针对各个不同的浏览器进行测试,修复,保证低级浏览器也有基本功能
- 区别: 渐进增强是向上兼容,优雅降级是向下兼容
5、网站性能优化的方案都有哪些?
1)尽量减少HTTP请求次数
- 合并js
- 合并css
- 图片sprite
2)延迟加载内容
- 图片懒加载
- 数据懒加载(点击查看更多)
- 功能懒加载(曝光或者点击后加载html模块、js功能模块)
3)使用离线缓存
- 把常用的变动又少的js、css、图片存储到localstorage,第二次访问的时候直接走本地缓存。在移动端使用广泛。
4)CSS、JS放置正确位置
- 把css放在head中,保证页面看到的时候样式是对的。
- 把js放到body里最后位置,防止加载js阻塞页面。
5)静态资源压缩
- 图片、CSS、JS在发布前要压缩。
6)静态资源使用多个域名
- 对于图片、CSS、JS,可使用几个域名,可以并发加载。
7)静态资源使用cdn存储
- 用户与你网站服务器的接近程度会影响响应时间的长短。 可以把静态资源放到内容分发网络(Content Delivery Network,CDN)中加快访问速度。
8)预加载
- 在某个功能还没展现时,在空闲时间预先加载相关图片或者js代码
9)DOM操作优化
- 使用JavaScript访问DOM元素比较慢,因此为了获得更多的应该页面,应该做到:
- 缓存已经访问过的有关元素
- 线下更新完节点之后再将它们添加到文档树中
- 避免使用JavaScript来修改页面布局
10)优化算法
- 在js处理中优化查找、排序算法。尽量少使用嵌套循环。
- 使用事件代理
6、Link和@import之间有什么区别?
- 本质的差别:link 属于 XHTML 标签,而 @import 完全是 CSS 提供的一种方式。
- 加载顺序的差别: 当一个页面被加载的时候(就是被浏览者浏览的时候) ,link 引用的 CSS 会同时被加载,而 @import 引用的 CSS 会等到页面全部被下载完再被加载。所以有时候浏览 @import 加载 CSS 的页面时开始会没有样式(就是闪烁),网速慢的时候还挺明显。
- 兼容性的差别: @import 是 CSS2.1 提出的,所以老的浏览器不支持,@import 只有在 IE5 以上的才能识别,而 link 标签无此问题。
- 使用 dom(document object model文档对象模型 )控制样式时的差别:当使用 javascript 控制 dom 去改变样式的时候,只能使用 link 标签,因为@import 不是 dom 可以控制的。
7、说说你对BFC的理解,触发条件有哪些?
官方定义:BFC(Block Formatting Context)块格式化上下文, 是Web页面的可视CSS渲染的一部分,是块盒子的布局过程发生的区域,也是浮动元素与其他元素交互的区域。
简单的理解:BFC就是一个块级容器,它会隔离外部,让盒子里面的元素不影响外面的元素,也就是在搭建页面的时候,不影响外面的布局。
BFC特性:
- 属于同一个BFC的两个相邻容器的上下margin会重叠(重点)
- 计算BFC高度时浮动元素也参于计算(重点)
- BFC的区域不会与浮动容器发生重叠(重点)
- BFC内的容器在垂直方向依次排列
- 元素的margin-left与其包含块的border-left相接触
- BFC是独立容器,容器内部元素不会影响容器外部元素
BFC的触发条件
一个HTML元素要创建BFC,则满足下列的任意一个或多个条件即可:
- 根元素;
- 浮动元素。元素的 float 不是 none;
- 绝对定位元素。元素的 position 为 absolute 或 fixed;
- 行内块元素。元素的 display 为 inline-block;
- 表格单元格。元素的 display为 table-cell,HTML表格单元格默认为该值;
- 表格标题。元素的 display 为 table-caption,HTML表格标题默认为该值;
- 匿名表格单元格元素。元素的 display为 table、table-row、 table-row-group、table-header-group、table-footer-group(分别是HTML table、row、tbody、thead、tfoot的默认属性)或 inline-table;
- overflow 值不为 visible 的块元素 ;
- 弹性元素。display为 flex 或 inline-flex元素的直接子元素;
- 网格元素。display为 grid 或 inline-grid 元素的直接子元素。
8、null,undefined 的区别
共同点:都是原始类型,保存在栈中变量本地
不同点:
(1)undefined——表示变量声明过但并未赋过值,它是所有未赋值变量默认值。
例如:var a; //a自动被赋值为undefined
(2)null——表示一个变量将来可能指向一个对象,一般用于主动释放指向对象的引用。
9、说说css中元素脱离文档流的方式有哪些?定位的方式有哪些以及区别?
脱离文档流的三种方法:
- float: 浮动,为元素设置float属性,可以让元素脱离原本的文档流独立开来,单独实现向左或向右,在设置float属性之后元素自动设置为块级元素,并且不会占据原本的位置。
- absolut: 绝对定位,absolut脱离的文档流是相对于其父元素的,而且这个父元素的position属性不为static(static为position默认属性), 如果absolute所在元素的父元素position属性为static则其继续向上寻找,直到找到符合要求的父元素。脱离文档流之后其他元素会无视此元素,其此元素不再占据原本的位置
- fixed:设置此属性的元素在位置上总是相对于body标签,也就是说在网页中设计此类标签不会随着网页的上下滑动而变化总是固定在网页的一个位置
定位的方式有哪些以及区别:
定位方式共有5种,分别是【静态定位static】,【相对定位relative】,【绝对定位abosolute】,【固定定位fixed】,【继承定位inherit】
静态定位static:
元素默认的位置,默认的定位方式就是static,这种定位方式只能用margin来改变位置,对left、top、z-index等设置值无效,这种定位不脱离文档流;
相对定位relative
基于元素自身变化之前的位置进行定位,可以通过设置left、top等值,使得指定元素相对其正常的位置进行偏移,这种定位不脱离文档流;
绝对定位abosolute:
绝对定位是根据设置有position属性,并且值不为static的父级进行定位;如果都没有已定位的祖先元素,则是基于浏览器窗口进行定位. margin的自动(auto)会失效,该方式脱离文档流
固定定位fixed:
基于浏览器窗口进行定位,并不会伴随屏幕滚动进行滚动,脱离文档流,不保留原来的位置,会改变元素的特性,父元素设置了固定定位,不用清除浮动的影响
继承定位inherit:
这种方式规定该元素继承父元素的position属性值。
10、同步和异步的区别
同步,是所有的操作都做完,才返回给用户结果。即写完数据库之后,在相应用户,用户体验不好。
异步,不用等所有操作等做完,就相应用户请求。即先相应用户请求,然后慢慢去写数据库,用户体验较好
11、伪类和伪元素的区别有哪些? Css3新增了哪些选择器
伪类和伪元素的区别有哪些:
1、伪类本质上是为了弥补常规CSS选择器的不足,以便获取到更多信息
2、伪元素本质上是创建了一个有内容的虚拟容器
3、CSS3中伪类和伪元素的语法不同
伪类 :link :hover 单冒号
伪元素 ::before ::after 双冒号
4、可以同时使用多个伪类,而只能同时使用一个伪元素
5、其中伪类和伪元素的根本区别在于:它们是否创造了新的元素,这个新创造的元素就叫 "伪无素"
6、伪元素/伪对象:不存在在DOM文档中,是虚拟的元素,是创建新元素。
这个新元素(伪元素)是某个元素的子元素,这个子元素虽然在逻辑上存在,但却并不实际存在于文档树中
7、伪类:存在dom文档中标签,在伪类时改变样式
8、因为伪类是类似于添加类所以可以是多个,而伪元素在一个选择器中只能出现一次,并且只能出现在末尾
Css3新增了哪些选择器:
1.属性选择器
通过“元素的属性”来选择元素的一种方式(属性选择器在CSS2.1中已经存在,只是进行了扩展)
实际运用场景:百度文库列表小图标(利用属性选择器去匹配a标签的href属性中的最后几个字符,也就是文件后缀名,然后分别添加图标就行了)
2.结构伪类选择器
- 子元素伪类选择器
- 指的是选择某一个元素下的子元素
- 子元素伪类选择器有两大类:
- :first-child、:last-child、:nth-child(n)、:only-child
12、说说Promise和async/await的区别是?
- promise和 async/await都是解决异步编程的一种方式,但是async/await使得异步代码看起来像同步代码。
- 函数前面多了一个async关键字。await关键字只能用于async定于的函数内。async函数会隐式地返回一个Promise,该promise的resolve值就是return的值。
为什么async/await更好?
使用async函数可以让代码简洁很多,不需要像Promise一样需要then,不需要写匿名函数处理Promise的resolve的值,也不需要定义多余的data变量,还避免了嵌套代码
async/await 让 try/catch可以同时处理同步和异步的错误。try/catch不能处理JSON.parse的错误,因为它在Promise中,我们需要使用.catch,这样的错误会显得代码非常的冗余
13、说说重排和重绘的区别?触发条件有哪些?
重排
当DOM的变化影响了元素的几何信息(元素的的位置和尺寸大小),使得部分渲染树 (或者整个染树)需要重新分析并且节点尺寸需要重新计算,表现为重新生成布局,重新排列元素,并将其安放在界面中的正确位置,这个过程叫做重排。
下面情况会发生重排:
- 页面初始渲染,这是开销最大的一次重排
- 添加/删除可见的DOM元素
- 改变元素位置.
- 改变元素尺寸,比如边距 (margin) 、填充(padding)、边框(border) 、宽度和高度等
- 改变元素内容,比如文字数量,图片大小你
- 改变元素字体大小
- 改变浏览器窗口尺寸
重绘
由于节点的样式发生改变,例如改变元素背景色时,屏幕上的部分内容需要更新,表现为某些元素的外观被改变,但没有改变布局。除此之外,重排也必然会触发重绘。
除了重排触发重绘,下面情况会发生重排:
- 改变颜色
- 通过 visibility: hidden 隐藏元素
- 改变 border-style
- 添加圆角、阴影
- outline
14、Javascript如何实现继承?
- 原型链继承
- 构造函数继承
- 实例继承
- 拷贝继承
- 组合继承
- 寄生组合式继承
点击查看详情
15、说说什么是严格模式,限制都有哪些?
- 严格模式通过抛出错误来消除了一些原有静默错误。
- 严格模式修复了一些导致 JavaScript引擎难以执行优化的缺陷:有时候,相同的代码,严格模式可以比非严格模式下运行得更快。
- 严格模式禁用了在ECMAScript的未来版本中可能会定义的一些语法。
严格模式主要有以下限制:
- 变量必须声明后再使用
- 函数的参数不能有同名属性,否则报错
- 不能使用with语句
- 不能对只读属性赋值,否则报错
- 不能使用前缀 0 表示八进制数,否则报错
- 不能删除不可删除的属性,否则报错
- 不能删除变量delete prop,会报错,只能删除属性delete global[prop]
- eval不会在它的外层作用域引入变量
- eval和arguments不能被重新赋值
- arguments不会自动反映函数参数的变化
- 不能使用arguments.callee
- 不能使用arguments.caller
- 禁止this指向全局对象
- 不能使用fn.caller和fn.arguments获取函数调用的堆栈
- 增加了保留字(比如protected、static和interface)
16、如何快速的让一个打乱一个数组的顺序,比如 var arr = [1,2,3,4,5,6,7,8,9,10];
var arr = [1,2,3,4,5,6,7,8,9,10] arr.sort(function(){ return Math.random() - 0.5; }); console.log(arr)
17、Vue2和Vue3中响应式原理及区别?
Vue2 响应式是通过 Object.defineProperty() 劫持各个属性 getter 和 setter,在数据变化时发布消息给订阅者,触发相应的监听回调。
存在几个问题:
初始化时需要遍历对象所有 key,如果对象层次较深,性能不好
通知更新过程需要维护大量 dep 实例和 watcher 实例,额外占用内存较多
Object.defineProperty 无法监听到数组元素的变化,只能通过劫持重写数方法
动态新增,删除对象属性无法拦截,只能用特定 set/delete 等API 代替
不支持 Map、Set 等数据结构
Vue3 中使用原生的 proxy 代替,支持监听对象和数组的变化,并且多达13种拦截方法,动态属性增删都可以拦截,新增数据结构全部支持,对象嵌套属性只代理第一层,运行时递归,用到才代理,也不需要维护特别多的依赖关系,性能取得很大进步
18、Vue是如何实现实现权限管理的,按钮级别权限如何实现?
- 权限管理一般需求是两个:页面权限和按钮权限
- 下面从前端方案和后端方案分开阐述:
- 前端方案会把所有路由信息在前端配置,通过路由守卫要求用户登录,用户登录后根据角色过滤出路由表。比如我会配置一个asyncRoutes数组,需要认证的页面在其路由的 meta 中添加一个 roles 字段,等获取用户角色之后取两者的交集,若结果不为空则说明可以访问。此过滤过程结束,剩下的路由就是该用户能访问的页面,最后通过router.addRoutes(accessRoutes)方式动态添加路由即可;
- 后端方案会把所有页面路由信息存在数据库中,用户登录的时候根据其角色查询得到其能访问的所有页面路由信息返回给前端,前端再通过addRoutes动态添加路由信息
- 按钮权限的控制通常会实现一个指令,例如v-permission,将按钮要求角色通过值传给v-permission指令,在指令的moutned钩子中可以判断当前用户角色和按钮是否存在交集,有则保留按钮,无则移除按钮(是DOM操作)。
- 纯前端方案的优点是实现简单,不需要额外权限管理页面,但是维护起来问题比较大,有新的页面和角色需求就要修改前端代码重新打包部署;服务端方案就不存在这个问题,通过专门的角色和权限管理页面,配置页面和按钮权限信息到数据库,应用每次登陆时获取的都是最新的路由信息,可谓一劳永逸!