Major06面试题综合
第二周
1、说说你对Event Loop
的理解?
1、Event Loop是JavaScript中的一种
机制
,用于处理异步事件
和回调函数
,它是JavaScript运行时环境的一个循环,不断从任务队列中取出任务并执行,直到任务队列为空。
2、Event Loop工作原理
:
a、执行同步代码,将异步操作放入任务队列中
b、当主线任务空闲的时候,Event Loop会检查任务队列中是否有任务
c、如果有任务,则取出任务并且执行
d、执行完成任务以后,再次检查任务队列,重复b和c的操作
3、Event Loop是JavaScript中非常重要的一个概念,它使得JavaScript可以处理异步操作,提高了程序的性能和用户体验。
2、说说你对BOM
的理解,常见的BOM对象
你了解哪些?
1、BOM就是指
浏览器对象模型
,提供了独立于内容与浏览器窗口进行交互的对象
2、它的作用就是跟浏览器做一些交互效果,比如如何进行页面的后退、前进、刷新、浏览器的窗口发生变化、滚动条的滚动,以及获取客户的一些信息,像浏览器品牌版本,屏幕分辨率
3、window:BOM的核心对象是window,它表示浏览器的一个实例,在浏览器中,window对象有双重角色,也就是浏览器窗口的一个接口,又是全局对象,因此,所有在全局作用域中声明的变量,函数都会编程window对象的属性和方法
4、local:
5、navigator:主要用来获取浏览器的属性,区分浏览器类型。属性较多,且兼容性比较复杂
6、screen:保存的纯粹是客户端能力信息,也就是浏览器窗口外面的客户端显示器的信息,比如像素宽度和像素高度
7、history:对象主要用来操作浏览器URL的历史记录,可以通过参数向前,向后,或者向指定URL跳转
3、浏览器的内核
都有哪些,什么区别
?
常见的浏览器内核有以下几种:
1.Trident内核
:是微软开发的浏览器内核,主要用于Internet Explorer浏览器。
2.Gecko内核
:是Mozilla Firefox浏览器的内核,也被其他浏览器所采用。
3.WebKit内核
:是苹果公司开发的浏览器内核,主要用于Safari浏览器和Chrome浏览器。
4.Blink内核
:是Google公司基于WebKit内核开发的浏览器内核,主要用于Chrome浏览器和Opera浏览器。
5、区别:
1、主要在于其渲染引擎
的不同,从而导致了浏览器的性能、兼容性、安全性等方面的差异。
2、Trident内核在处理CSS和JavaScript方面相对较慢
3、Gecko内核则更加注重安全性和隐私保护
4、WebKit内核则以其快速的渲染速度和良好的兼容性著称
5、Blink内核则在性能和稳定性方面有所提升。
4、说说浏览器的渐进增强
和优雅降级
的区别?
1、浏览器的渐进增强和优雅降级都是为了解决不同的浏览器或者设备之间的兼容性问题
2、渐进增强就是指在设计和开发网站或应用程序的时候,首先考虑基本功能的实现,然后逐步添加更加高级的功能和交互的效果,以适应不同的浏览器和设备的能力
3、渐进增强更加注重于向前兼容性,就算在比较老的浏览器上也可以正常使用
4、优雅降级就是指在设计和开发网站或者应用程序的时候,首先考虑高级功能和交互效果的实现,然后逐步降低要求,用来适应较老或者不支持这些功能的浏览器和设备
5、优雅降级就是强调向后兼容性,也就是说在较新的浏览器上能够享受更好的用户体验
5、 网站性能优化
的方案都有哪些?
1、尽量减少HTTP的请求次数:合并js、css等
2、 压缩文件:压缩CSS、JavaScript、HTML等文件,减少文件大小,提高网页加载速度。
3、 图片优化:使用适当的图片格式,压缩图片大小,减少图片数量,提高网页加载速度。
4、CDN加速:使用CDN(内容分发网络)加速网站访问速度,将网站内容分发到全球各地的服务器上,使用户可以从最近的服务器获取内容。
5、缓存优化:使用浏览器缓存和服务器缓存,减少重复请求,提高网站访问速度。
6、前端优化:减少HTTP请求,使用CSS Sprites、合并JavaScript文件等技术,减少页面加载时间。
7、数据库优化:优化数据库查询语句,使用索引,减少数据库查询时间,提高网站访问速度。
8、服务器优化:使用高性能服务器,优化服务器配置,提高网站访问速度。
9、去除冗余代码:去除无用的代码,减少页面大小,提高网站访问速度。
10、响应式设计:使用响应式设计,使网站可以适应不同的设备和屏幕大小,提高用户体验。
6、Link
和@import
之间有什么区别?
1、Link和@import都是用于引入外部资源的方法
2、不同:
1、加载顺序的不同:Link标签在加载页面的时候就会同时加载外部的资源,而@import在页面加载完毕之后才会加载外部资源
2、兼容性的不同:Link标签在所有浏览器中都被支持,而@import在一些旧的版本浏览器中可能不被支持
3、作用范围不同:Link标签可以用于引入各种类型的资源,包括CSS、JavaScript、图像等,而@import只能用于引入css文件
4、优先级不同:Link标签的优先级高于@import,因此如果同一个样式表这两种方法都使用的话,那么Link就会覆盖@import的样式
7、说说你对BFC
的理解,触发条件有哪些?
1、BFC就是
块级格式化上下文
,是指的独立的渲染区域,其中的元素按照一定的规则进行布局和渲染
2、BFC特点:
1、内部元素在垂直方向上一个接一个的排列,形成一个垂直流
2、BFC区域不会与浮动元素重叠
3、BFC区域不会与外部元素的margin发生重叠
4、BFC区域可以包含浮动元素
5、BFC区域可以防止元素被父元素的边框所覆盖
3、触发条件:
1、根元素或者包含根元素的元素
2、浮动元素float不等于none
3、绝对定位position为absoulute或者fixed
4、display是inline-block、table-cell、table-caption、flex、inline-flex
5、overflow不为visible的块级元素
8、null,undefined
的区别?
1、在js中,null和undefined都是表示没有值
2、区别:
1、undefined表示一个变量声明了但是没有被赋值,或者对象属性不存在
2、null表示一个变量已经被赋值为null,或者对象属性被赋值为null
3、在条件语句中,undefined和null都会被转换为false,但是在比较运算符中,行为不同,undefined与任何值包括本身比较都是false,但是null只在和undefined比较是为true
9、说说css中元素脱离文档流
的方式有哪些?定位的方式
有哪些以及区别?
1、CSS中元素脱离文档流的方式有以下几种:
- 浮动(float):将元素从文档流中移出来,使其能够与其他元素并排显示。
- 绝对定位(position: absolute):将元素从文档流中移出来,并相对于其最近的已定位祖先元素进行定位。
- 固定定位(position: fixed):将元素从文档流中移出来,并相对于浏览器窗口进行定位。
- 弹性布局(display: flex):通过设置父元素为弹性容器,使其子元素能够脱离文档流,并按照一定的规则进行排列。
- 网格布局(display: grid):通过设置父元素为网格容器,使其子元素能够脱离文档流,并按照一定的规则进行排列。
2、定位的方式有以下几种:
- 相对定位(position: relative):相对于元素在文档流中的位置进行定位,不会影响其他元素的位置。
- 绝对定位(position: absolute):相对于最近的已定位祖先元素进行定位,如果没有已定位的祖先元素,则相对于文档的 body 元素进行定位。
- 固定定位(position: fixed):相对于浏览器窗口进行定位,不会随着页面滚动而移动。
3、区别:
相对定位和绝对定位的区别在于,相对定位不会脱离文档流,而绝对定位会脱离文档流。固定定位与绝对定位类似,但它相对于浏览器窗口进行定位,不会随着页面滚动而移动。
10、同步
和异步
的区别?
1、同步和异步是指在进行任务处理的时候,
任务的执行方式不同
2、同步任务指的是任务按照顺序依次执行,每个任务必须等待前一个任务完成之后才能执行,在同步执行中,任务的执行是阻塞的,也就是说在执行任务的时候会一直等待任务完成后才会继续执行下一个任务
3、异步执行是指任务不按照顺序依次执行,每一个任务可以独立执行,不需要等待前一个任务完成。在异步任务的执行中,任务的执行是非阻塞的,也就是执行任务是不会等待任务完成,而是继续执行下一个任务
4、同步和异步的区别就在于任务的执行方式,同步执行就是按照顺序依次执行,而异步执行时独立执行,不需要等待前一个任务的完成,在实际中,异步执行通常能够提高程序的响应速度和效率
11、伪类
和伪元素
的区别有哪些? Css3
新增了哪些选择器
?
伪类和伪元素的区别:
- 伪类用于描述元素的一些特殊状态,如:hover、:active、:focus等,而伪元素用于创建一些不在文档树中的元素,如::before、::after等。
- 伪类在CSS2中以单冒号(:)表示,伪元素以双冒号(::)表示。
- 伪类可以用于任何元素,而伪元素只能用于某些特定的元素。
- 伪类可以用于选择器的任何位置,而伪元素只能用于选择器的最后一个位置。
CSS3新增的选择器包括:
- 属性选择器:[attr=value]、[attr~=value]、[attr|=value]、[attr^=value]、[attr$=value]、[attr*=value]
- 伪类选择器::nth-child()、:nth-last-child()、:nth-of-type()、:nth-last-of-type()、:first-child、:last-child、:first-of-type、:last-of-type、:only-child、:only-of-type、:not()
- 伪元素选择器:::before、::after、::first-letter、::first-line、::selection
- 组合选择器:A B、A > B、A + B、A ~ B
12、说说Promise
和async/await
的区别是?
Promise和async/await都是用于处理异步操作的方式,但是它们之间有一些区别。
1. 语法:
Promise是一种基于回调函数的异步编程方式,使用.then()和.catch()方法来处理异步操作的结果。而async/await是ES2017引入的异步编程方式,使用async和await关键字来处理异步操作的结果。
2.可读性:
async/await相对于Promise来说更加易读易懂,代码更加简洁明了。
3.错误处理:
在Promise中,错误处理需要使用.catch()方法来捕获错误。而在async/await中,可以使用try/catch语句来捕获错误。
4.链式调用:
Promise可以链式调用多个异步操作,而async/await只能在一个异步操作完成后再进行下一个异步操作。
总的来说,async/await是一种更加直观、易读、易懂的异步编程方式,但是在某些情况下,Promise也是非常有用的。
13、说说重排
和重绘
的区别?触发条件有哪些?
重排和重绘是浏览器渲染页面时的两个重要概念。
重排(reflow)
是指当页面中的元素发生布局变化时,浏览器需要重新计算元素的位置和大小,并重新排列页面的布局。重排会导致页面的重新布局和重新渲染,是一种比较耗费性能的操作。
重绘(repaint)
是指当页面中的元素的样式发生变化时,浏览器需要重新绘制元素的样式。重绘不会改变页面的布局,只会重新绘制元素的样式,因此比重排的性能开销要小。
触发重排的条件包括:
- 页面初次渲染
- 浏览器窗口大小发生变化
- 元素的位置、大小、内容发生变化
- 元素的样式发生变化
- 页面滚动
触发重绘的条件包括:
- 元素的样式发生变化
- 元素的背景色、边框颜色、文本颜色等属性发生变化
- 元素的透明度发生变化
- 元素的文本内容发生变化
总的来说,重排和重绘都会影响页面的性能,因此在开发过程中需要尽量避免频繁触发重排和重绘。可以通过合理的布局设计、使用 CSS3 动画代替 JavaScript 动画等方式来优化页面性能。
14、Javascript如何实现继承
?
1、
原型链继承:
通过将子类的原型对象指向父类的实例对象来实现继承。
2、构造函数继承:
指通过在子类构造函数中调用父类构造函数来实现继承。
3、组合继承:
组合继承指的是将原型链和构造函数继承结合起来的一种继承方式,实现方式就是通过在子类构造函数中调用父类构造函数来继承父类的属性,并将子类的原型对象指向一个新的父类实例对象来继承的方法。
4、ES6中的class继承
:通过使用extends关键字来继承父类,并使用super来调用父类的构造函数和方法。
15、说说什么是严格模式
,限制都有哪些?
严格模式是 JavaScript 的一种执行模式,它强制执行一些限制,以帮助开发者编写更加健壮的代码。
在严格模式下,一些不安全的行为会被禁止,一些错误也会被抛出。
严格模式下的限制包括:
- 禁止使用未声明的变量。
- 禁止删除变量、函数或函数参数。
- 禁止使用 eval() 函数创建变量或函数。
- 禁止使用 with 语句。
- 禁止在函数内部使用 arguments.callee 和 arguments.caller。
- 禁止对只读属性赋值。
- 禁止扩展内置对象的原型。
- 禁止在函数内部重复声明变量。
严格模式可以通过在代码的开头添加 “use strict”; 来启用。在严格模式下编写代码可以帮助开发者避免一些常见的 JavaScript 错误,并提高代码的可读性和可维护性。
16、如何快速的让一个打乱一个数组的顺序
,比如 var arr = [1,2,3,4,5,6,7,8,9,10]?
- 从数组的最后一个元素开始,向前遍历数组。
- 随机生成一个 0 到当前遍历的索引值之间的整数。
- 将当前遍历的元素与随机生成的索引所对应的元素交换位置。
- 继续向前遍历数组,重复步骤 2 和 3,直到遍历到数组的第一个元素为止。
17、Vue的自定义指令钩子函数
有哪些?你用自定义指令做过什么?
Vue的自定义指令钩子函数包括:bind、inserted、update、componentUpdated、unbind。
1、bind
:只调用一次,指令第一次绑定到元素时调用,可以在这里进行一次性的初始化设置。
2、inserted
:被绑定元素插入父节点时调用,但可能在其父节点还未插入到DOM中。
3、update
:被绑定元素所在的模板更新时调用,而不论绑定值是否变化。通过比较更新前后的绑定值,可以忽略不必要的模板更新。
4、componentUpdated
:被绑定元素所在模板完成一次更新周期时调用。
5、unbind
:只调用一次,指令与元素解绑时调用。
我曾经使用自定义指令实现了一个点击外部区域关闭弹窗的功能。具体实现方式是在bind钩子函数中绑定一个document的click事件,当点击事件触发时判断点击的区域是否在弹窗内部,如果不是则关闭弹窗。在unbind钩子函数中解绑该事件。
18、从A页面跳转到B页面,缓存A组件,从A组件跳转到C组件,取消缓存,如何实现?
1、
keep-alive
可以通过当前页面的BeforeRouter(to,from,next)
当to ===“B” & from ===”A” keep-alive的meta中参数为true
当to ===“C” & from ===”A” keep-alive的meta中参数为false
2、生命周期,获取 this.router.meta
修改页面的meta里面的参数,keep-alive回根据meta中的参数决定是否对组件进行缓存
19、Vue2
和Vue3
中响应式原理及区别?
1、Vue2和Vue3中的响应式原理都是基于
Object.defineProperty
实现的。当数据发生变化时,会自动触发视图的更新。但是Vue3中对响应式原理进行了优化,使用了Proxy代理对象来替代了Object.defineProperty,使得响应式系统更加高效和灵活。
2、Vue2中的响应式原理是在实例化Vue对象时,会对data中的每个属性进行递归地遍历,将每个属性都转换为getter和setter,当属性被访问或修改时,会触发getter和setter方法,从而实现响应式更新。
3、Vue3中的响应式原理使用了Proxy代理对象,它可以拦截对象的访问和修改操作,从而实现响应式更新。Vue3中的响应式系统还支持了reactive函数,可以将一个普通对象转换为响应式对象,使得开发者可以更加灵活地使用响应式系统。
4、总的来说,Vue3中的响应式系统相比Vue2更加高效和灵活,但是在使用上也有一些区别,需要开发者进行适当的学习和调整。
20、Vue是如何实现实现权限管理
的,按钮级别权限如何实现?
1、
将所有权限按照等级
,划分为一级权限和二级权限,生成相对的tree数,获取每个权限的id,将每个id放到一个列表中,赋值给角色的权限外键
2、按钮权限
是,每个按钮绑定一个处理方法,当登录的用户,返回的角色id没有对应这个按钮的权限方法时候,会对按钮进行隐藏处理
第一周
21、Vue2
和Vue3
的区别至少说5点?
性能优化
:Vue3在性能方面进行了大量的优化,包括编译器优化、响应式系统优化、虚拟DOM优化等,使得Vue3的性能比Vue2更快。Composition API
:Vue3引入了Composition API,它是一种新的API风格,可以更好地组织和重用组件逻辑,使得代码更加清晰和易于维护。TypeScript支持
:Vue3对TypeScript的支持更加完善,可以更好地进行类型检查和代码提示,提高代码的可靠性和可维护性。更好的Tree-Shaking:
Vue3采用了更加现代的ES模块语法,可以更好地支持Tree-Shaking,减小打包体积。更好的适配性:
Vue3对Web和移动端的适配性更加优秀,可以更好地支持PWA和SSR等技术。更好的错误处理:
Vue3引入了错误处理机制,使得开发者能够更加容易地定位和解决错误。
22、 Vue3中组件通信的流程【父传子,子传父】
?
1、vue3中组件通信的流程分为父传子、子传父两种方式
2、父传子:
父组件通过props向子组件传递数据,子组件通过props接收数据。父组件可以在模板中使用子组件,并且通过v-bind指令将数据传递给子组件,子组件可以在props中声明接收的数据类型和默认值
3、子传父:
子组件通过$emit
的方法向父组件发送事件,父组件通过v-on
指令监听子组件发送的事件,子组件可以通过$emit
方法来传递给父组件
23、Apply/call/bind
的原理是什么?
1、Apply、call和bind都是JavaScript中用于改变函数执行上下文的方法。
2、allpy和call的作用都是一样的,都是改变函数的执行上下文,就是改变函数内部的this指向,它们的区别就在于传参的方式不同,apply接收一个数组作为参数,call接收多个参数
3、bind方法也是用于改变函数的执行上下文,但是他不会立即执行函数,而是返回一个新的函数,这个新的函数的this指向被绑定的对象
4、总的来说,apply
、call
和bind
都是用于改变函数执行上下文的方法,它们的区别在于传参的方式和返回值。apply和call会立即执行函数,而bind会返回一个新的函数。
24、说说你对原型
和原型链
的理解?
1、
原型
是JavaScript中的一个重要概念,它是一个对象,其他对象可以通过它来实现属性和方法的继承。每个JavaScript对象都有一个原型对象,它定义了该对象的属性和方法。如果在当前对象中找不到某个属性或方法,JavaScript引擎会自动查找该对象的原型对象,直到找到为止。
2、原型链
是由原型对象组成的链式结构,它是JavaScript中实现继承的一种方式。当一个对象需要访问另一个对象的属性或方法时,JavaScript引擎会沿着原型链向上查找,直到找到该属性或方法为止。如果在整个原型链中都找不到该属性或方法,则返回undefined。
3、在JavaScript中,每个对象都有一个__proto__属性,它指向该对象的原型对象。当我们访问一个对象的属性或方法时,JavaScript引擎会先查找该对象自身是否有该属性或方法,如果没有,则会沿着原型链向上查找,直到找到为止。如果在整个原型链中都找不到该属性或方法,则返回undefined。
4、总之,原型和原型链是JavaScript中非常重要的概念,它们可以帮助我们实现对象之间的继承和共享属性和方法。
25、说说你对ES6中Generator
的理解?
1、ES6中的Generator是一种特殊的函数,它可以在执行过程中暂停并保存当前的状态,然后在需要的时候恢复执行。
Generator函数通过yield关键字来实现暂停和恢复执行的功能。
2、Generator函数可以用于异步编程
,可以通过yield关键字来暂停异步操作的执行,等待异步操作完成后再继续执行。Generator函数还可以用于实现迭代器,可以通过yield关键字来返回一个值,然后在下一次调用时继续执行。
3、另外,Generator函数还可以接受参数,可以在调用Generator函数时传入参数,然后在函数内部使用这些参数。
4、总之,Generator函数是一种非常强大的工具,可以用于实现异步编程、迭代器等功能,可以大大简化代码的编写和维护。
26、说说浏览器事件循环
和nodeJs的事件循环
的区别?
浏览器事件循环和Node.js的事件循环有以下几个区别:
- 浏览器事件循环是单线程的,而Node.js的事件循环是多线程的。
- 浏览器事件循环中的任务分为宏任务和微任务两种,而Node.js的事件循环中只有宏任务。
- 浏览器事件循环中的微任务包括Promise、MutationObserver和process.nextTick,而Node.js的事件循环中没有process.nextTick,但有setImmediate。
- 浏览器事件循环中的宏任务包括script、setTimeout、setInterval、I/O、UI rendering等,而Node.js的事件循环中的宏任务包括I/O、定时器、setImmediate等。
- 浏览器事件循环中的任务执行顺序是先执行所有微任务,再执行一个宏任务,而Node.js的事件循环中的任务执行顺序是先执行所有的I/O和定时器任务,再执行setImmediate任务。
总的来说,浏览器事件循环和Node.js的事件循环都是基于事件驱动的模型,但是它们的实现方式和任务执行顺序有所不同。
27、说说你对浏览器缓存机制
的理解?
浏览器缓存机制是指
浏览器在访问网页时,会将一些静态资源(如图片、CSS、JS等)缓存到本地,以便下次访问同一网页时可以直接从本地缓存中读取,从而提高网页加载速度和用户体验。
1、浏览器缓存机制分为两种:强缓存
和协商缓存。
2、强缓存
是指浏览器在第一次请求资源时,会将资源的过期时间(Expires)或最大缓存时间(Cache-Control)存储在本地,下次请求时会先判断本地缓存是否过期,如果没有过期则直接从本地缓存中读取资源,不会向服务器发送请求。
3、协商缓存
是指浏览器在第一次请求资源时,会将资源的标识(ETag或Last-Modified)存储在本地,下次请求时会向服务器发送请求,服务器会根据资源的标识判断资源是否有更新,如果没有更新则返回304状态码,浏览器直接从本地缓存中读取资源。
4、浏览器缓存机制可以有效减少网络请求,提高网页加载速度和用户体验,但也可能导致资源更新不及时,需要在开发中合理使用缓存机制,避免出现问题。
28、说说你对浏览器内核
的理解?
浏览器内核又可以分为两个部分:
渲染引擎
和JS引擎
1、渲染引擎
:负责取得网页的内容(HTML,XML,图像等等)、整理讯息(加入css等),以及计算网页的显示方式,然后会输出至显示器或打印机。浏览器内核的不同对于网页的语法解释会有所不同,所以渲染的效果也不同
2、JS引擎
:则是解析JavaScript语言,执行JavaScript语言来实现网页的动态效果
浏览器内核的不同会影响浏览器的渲染效果、速度、兼容性等方面,因此选择合适的浏览器内核对于浏览器的性能和用户体验都非常重要。
29、说说你对Vue的响应式原理
的理解?
Vue的响应式原理是通过
数据劫持
来实现的。当一个Vue实例被创建时,Vue会对其所有的数据进行监听,当数据发生变化时,Vue会自动更新视图。
具体实现方式如下:
- Vue会在实例化时对data对象进行遍历,将每个属性转换为getter/setter,这样当属性被访问或修改时,Vue能够监听到。
- 当数据发生变化时,Vue会通过setter方法监听到变化,并通知所有依赖该数据的组件进行更新。
- Vue使用了一个Dep类来管理所有的依赖关系,每个数据都会对应一个Dep实例,当数据发生变化时,Dep会通知所有依赖该数据的Watcher实例进行更新。
- Watcher实例是Vue中的一个重要概念,它会在组件渲染时被创建,并且会在数据发生变化时被通知进行更新。每个Watcher实例都会与一个Dep实例关联,当数据发生变化时,Dep会通知所有关联的Watcher实例进行更新。
总的来说,Vue的响应式原理是通过数据劫持、Dep类和Watcher实例来实现的,它能够自动监听数据变化并更新视图,大大简化了开发过程。
30、Methods\ watch \computed
区别是什么?
1、Methods 和 watch 都是 Vue.js 中用于
监听数据变化
的方式
2、Methods
是 Vue.js 中的一个选项,用于定义组件中的方法。它可以接受参数,执行一些操作,并返回结果。当组件中的数据发生变化时,如果需要重新计算某些数据,就需要在方法中重新计算并返回结果。
3、Watch
是 Vue.js 中的一个特殊选项,用于监听数据的变化并执行一些操作
。它可以监听一个或多个数据的变化,并在数据变化时执行指定的回调函数。当需要在数据变化时执行一些异步操作或复杂的计算时,就需要使用 watch。
4、区别在于
:
1、Methods 是用于定义组件中的方法,可以接受参数并执行一些操作,返回结果。而 watch 是用于监听数据变化并执行一些操作,不能接受参数,也不能返回结果。
2、Methods 通常用于计算属性或处理事件等简单的操作,而 watch 通常用于处理复杂的异步操作或计算,或者需要监听多个数据变化的情况。
31、说说你对Virtual DOM
的理解?
Virtual DOM是一种用于
优化Web应用程序性能
的技术。它是一个轻量级的JavaScript对象,它模拟了真实DOM的层次结构和属性,并且可以在内存中进行操作,而不是直接操作真实DOM。当Virtual DOM发生变化时,它会与真实DOM进行比较,只更新需要更新的部分,从而减少了DOM操作的次数,提高了应用程序的性能
。
Virtual DOM的优点包括:
- 提高应用程序的性能:由于Virtual DOM只更新需要更新的部分,因此减少了DOM操作的次数,提高了应用程序的性能。
- 简化应用程序的开发:由于Virtual DOM可以在内存中进行操作,因此可以更轻松地进行应用程序的开发和测试。
- 提高应用程序的可维护性:由于Virtual DOM可以更轻松地进行应用程序的开发和测试,因此可以提高应用程序的可维护性。
总之,Virtual DOM是一种非常有用的技术,可以帮助我们提高Web应用程序的性能和可维护性。
32、说说你对nextTick
的理解和作用?
1、nextTick是Vue.js中的一个异步方法,它的作用
是在下一次DOM更新循环结束之后执行指定的回调函数
。nextTick的主要作用是在Vue.js更新DOM之后,立即执行一些操作,例如更新数据后立即获取DOM元素的尺寸或位置等。
2、nextTick的实现原理是利用了JavaScript的事件循环机制。当Vue.js更新DOM时,它会将所有的DOM更新操作放入一个队列中,然后等待下一次事件循环时执行。而nextTick方法就是将指定的回调函数放入这个队列中,等待下一次事件循环时执行。
3、nextTick的使用场景比较广泛,例如在Vue.js中使用$nextTick方法可以在DOM更新后立即执行一些操作,例如获取DOM元素的尺寸或位置等。另外,在Vue.js中使用nextTick方法也可以解决一些异步更新数据的问题,例如在更新数据后立即获取更新后的数据。
4、总之,nextTick是Vue.js中非常重要的一个异步方法,它可以帮助我们在DOM更新后立即执行一些操作,从而提高应用程序的性能和用户体验。
33、说说你对webpack
的理解?
Webpack是一个
现代化的JavaScript应用程序打包工具
。它可以将多个JavaScript文件、CSS文件、图片等静态资源打包成一个或多个bundle文件,以便于在浏览器中加载和使用。
Webpack的主要功能包括:
模块化管理
:Webpack支持CommonJS、AMD、ES6等多种模块化规范,可以将多个模块打包成一个文件,减少HTTP请求次数,提高页面加载速度。代码转换
:Webpack可以将ES6、TypeScript、CoffeeScript等高级语言转换成浏览器可识别的JavaScript代码。代码分割
:Webpack可以将应用程序分割成多个chunk,实现按需加载,提高页面加载速度。资源管理
:Webpack可以处理CSS、图片、字体等静态资源,将它们打包成一个或多个文件,并且可以对它们进行压缩、优化等操作。插件系统
:Webpack提供了丰富的插件系统,可以实现各种自动化操作,如代码压缩、文件复制、HTML生成等。
总之,Webpack是一个非常强大的工具,可以帮助开发者更好地管理和打包JavaScript应用程序,提高开发效率和用户体验。
34、谈谈GET
和POST
的区别?
1、GET和POST是
HTTP协议中常用的两种请求方法
2、区别:
- GET请求方法是用于获取资源,而POST请求方法是用于提交数据。
- GET请求方法的数据会附加在URL后面,以问号“?”分隔,参数之间以“&”符号分隔,而POST请求方法的数据则包含在请求体中。
- GET请求方法的数据传输量较小,一般不超过2KB,而POST请求方法的数据传输量较大,可以传输任意大小的数据。
- GET请求方法的数据可以被缓存,可以被收藏为书签,可以被浏览器历史记录记录,而POST请求方法的数据不会被缓存,也不能被收藏为书签,也不会被浏览器历史记录记录。
- GET请求方法的安全性较低,因为数据会被暴露在URL中,容易被截获和篡改,而POST请求方法的安全性较高,因为数据不会被暴露在URL中,只有请求体中的数据才能被截获和篡改。
35、说说HTTP
和HTTPS
的区别,HTTPS加密原理
是?
1、HTTP是
超文本传输协议
,是一种用于传输数据的协议
,它是明文
传输的,数据容易被窃听和篡改。
2、而HTTPS是在HTTP的基础上加入了SSL/TLS协议
,通过加密和认证技术保证数据的安全性。HTTPS使用的是加密
传输,数据传输过程中会进行加密,保证数据的机密性和完整性。
3、具体来说,HTTPS在传输数据之前会先进行SSL/TLS握手,建立安全通道,然后再进行数据传输。SSL/TLS协议使用了非对称加密和对称加密两种加密方式,非对称加密用于建立安全通道,对称加密用于加密数据传输。
4、在SSL/TLS握手过程中,服务器会向客户端发送自己的公钥,客户端使用该公钥加密一个随机数,然后发送给服务器,服务器使用自己的私钥解密该随机数,然后使用该随机数生成对称密钥,用于加密数据传输。
5、HTTPS相对于HTTP来说,具有更高的安全性和保密性,适用于需要保护用户隐私和敏感信息的网站,如银行、电商等网站。
36、TCP为什么要三次握手
?
TCP协议需要进行三次握手来建立连接,主要是
为了确保通信双方都能够正常收发数据。
具体原因如下:
1. 第一次握手:
客户端向服务器发送连接请求报文段,服务器收到请求后会回复一个确认报文段,表示已经收到了客户端的请求。
2.第二次握手:
服务器收到客户端的请求后,会向客户端发送一个确认报文段,表示已经收到了客户端的请求,并准备好了与客户端进行通信。
3.第三次握手:
客户端收到服务器的确认报文段后,会向服务器发送一个确认报文段,表示已经收到了服务器的确认,并准备好了与服务器进行通信。
4、通过三次握手,可以确保通信双方都能够正常收发数据,并且可以避免因网络延迟或丢包等问题导致连接失败或数据传输错误的情况发生。同时,三次握手还可以防止因网络中的恶意攻击或误传等问题导致的安全问题。
37、说说Proxy代理
的原理?
Proxy代理是一种
网络应用程序
,它充当客户端和服务器之间的中介。它的原理是在客户端和服务器之间建立一个代理服务器,客户端向代理服务器发送请求,代理服务器再将请求转发给服务器,服务器响应后将结果返回给代理服务器,代理服务器再将结果返回给客户端
。Proxy代理的
工作流程
如下:
- 客户端向代理服务器发送请求。
- 代理服务器接收请求,并将请求转发给服务器。
- 服务器响应请求,并将结果返回给代理服务器。
- 代理服务器接收到结果,并将结果返回给客户端。
Proxy代理的作用主要有以下几个方面:
- 提高访问速度:代理服务器可以缓存请求结果,当下次有相同的请求时,直接返回缓存结果,从而提高访问速度。
- 访问控制:代理服务器可以对客户端的请求进行过滤和控制,例如限制访问某些网站或者限制某些客户端的访问。
- 隐藏客户端信息:代理服务器可以隐藏客户端的真实IP地址,从而保护客户端的隐私。
- 负载均衡:代理服务器可以将请求分发到多个服务器上,从而实现负载均衡,提高服务器的性能和可靠性。
总之,Proxy代理是一种非常有用的网络应用程序,它可以提高访问速度、保护隐私、实现负载均衡等多种功能。
38、说说内存泄漏
的理解?内存泄漏的情况有哪些?
内存泄漏指
程序在运行过程中,申请的内存空间没有被正确释放,导致系统中的可用内存不断减少,最终导致程序崩溃或系统崩溃的现象
。内存泄漏通常是由于程序中存在一些错误的内存管理操作,例如未释放动态分配的内存
、重复释放内存
、使用已经释放的内存
等。内存泄漏的情况有以下几种:
动态分配内存后未释放
:程序在运行过程中使用了动态分配的内存,但在使用完毕后未将其释放,导致内存泄漏。循环引用:
当两个或多个对象相互引用时,如果它们之间的引用关系没有被正确处理,就会导致内存泄漏。文件未关闭
:程序在使用文件时,如果没有正确关闭文件,就会导致内存泄漏。缓存未清理
:程序在使用缓存时,如果没有正确清理缓存,就会导致内存泄漏。
5.程序错误:
程序中存在一些错误的内存管理操作,例如使用已经释放的内存、重复释放内存等,都会导致内存泄漏。内存泄漏会导致程序运行速度变慢,甚至会导致程序崩溃或系统崩溃,因此在程序开发中,需要注意内存管理,及时释放不再使用的内存空间。
第三周
39、说说箭头函数
和普通函数
的区别?
箭头函数和普通函数的区别主要有以下几点:
- 箭头函数没有自己的this,它的this是继承自外层作用域的。而普通函数的this是在函数被调用时动态绑定的,它的值取决于函数的调用方式。
- 箭头函数不能使用arguments对象,也不能使用new关键字调用。而普通函数可以使用arguments对象,也可以使用new关键字调用。
- 箭头函数没有prototype属性,因此不能作为构造函数使用。而普通函数可以作为构造函数使用,创建新的对象实例。
- 箭头函数的语法更加简洁,可以省略函数体中的return关键字和花括号。而普通函数必须使用return关键字返回值,并且函数体必须用花括号括起来。
5、总的来说,箭头函数适合用于简单的函数,可以让代码更加简洁易读。而普通函数则更加灵活,可以应对各种不同的场景。
40、SPA首屏加载速度慢
怎么解决?
代码优化:
检查代码中是否存在冗余、重复或不必要的代码,尽可能减少代码量,优化代码结构和算法,以提高页面加载速度。
2.图片优化:
对于图片过大的情况,可以使用图片压缩工具进行压缩,减小图片大小,从而提高页面加载速度。
3.懒加载:
对于页面中的图片、视频等资源,可以使用懒加载技术,只有当用户滚动到相应位置时才加载,从而减少首屏加载时间。CDN加速:
使用CDN(Content Delivery Network)加速服务,将静态资源分布在全球各地的服务器上,从而提高页面加载速度。缓存优化:
使用浏览器缓存技术,将页面中的静态资源缓存到本地,下次访问时直接从缓存中读取,从而减少服务器请求,提高页面加载速度。服务器优化:
对于服务器响应速度慢的情况,可以考虑使用更高配置的服务器,或者使用负载均衡技术,将请求分散到多个服务器上,从而提高页面加载速度。
41、说说webpack中常见的Loader
?解决了什么问题?
babel-loader:
将ES6/ES7/JSX等语法转换为ES5语法,解决了浏览器兼容性问题。
2.css-loader:
解析CSS文件,处理其中的依赖关系,例如@import和url()等,使得CSS文件可以被打包到JS文件中。
3.style-loader:
将CSS代码注入到HTML页面中的
42、你对SPA单页面
的理解,它的优缺点
分别是什么?如何实现SPA应用
呢?
SPA单页面应用是指
整个应用只有一个页面,所有的页面内容都是通过异步加载数据并动态更新页面来实现的
。SPA应用通常使用前端框架(如React、Angular、Vue等
)来实现。
优点:
- 用户体验好:SPA应用可以实现无刷新页面切换,用户体验更加流畅。
- 前后端分离:SPA应用可以将前端和后端分离,前端只需要关注页面展示和交互逻辑,后端只需要提供API接口。
- 提高性能:SPA应用可以减少页面刷新,减少服务器负担,提高性能。
缺点:- 首屏加载慢:SPA应用需要加载所有的前端代码和数据,首屏加载时间较长。
- SEO不友好:由于SPA应用只有一个页面,搜索引擎难以抓取页面内容,对SEO不友好。
- 浏览器兼容性问题:SPA应用需要使用HTML5的一些新特性,对浏览器的兼容性要求较高。
实现SPA应用的方法:- 使用前端框架:使用React、Angular、Vue等前端框架可以快速实现SPA应用。
- 使用路由库:使用React Router、Vue Router等路由库可以实现页面的无刷新切换。
- 使用AJAX技术:使用AJAX技术可以实现异步加载数据,动态更新页面内容。
43、Vue中组件
和插件
有什么区别?
Vue中组件和插件的区别如下:
- 组件是Vue中的基本概念,是Vue应用中的可复用的代码块,用于封装UI组件或业务逻辑。组件可以在Vue应用中多次使用,可以接收父组件传递的数据,也可以向父组件发送数据。
- 插件是Vue中的扩展功能,是一些可选的功能模块,用于增强Vue应用的功能。插件可以添加全局方法或属性,也可以添加全局指令或过滤器,还可以添加Vue实例方法或混入。
- 组件和插件的使用方式也不同。组件需要在Vue应用中注册后才能使用,可以通过Vue.component()方法或Vue.extend()方法来注册组件。而插件可以通过Vue.use()方法来安装插件,也可以直接在Vue实例中使用。
- 组件和插件的作用范围也不同。组件主要用于封装UI组件或业务逻辑,作用范围通常是局部的,只在某个组件内部使用。而插件主要用于增强Vue应用的功能,作用范围通常是全局的,可以在整个Vue应用中使用。
44、Vue组件之间的通信方式
都有哪些?
Vue组件之间的通信方式有以下几种:
父子组件通信:
父组件通过props向子组件传递数据,子组件通过事件向父组件传递数据。
2.兄弟组件通信:
可以通过一个共同的父组件作为中介,将数据传递给兄弟组件。
3.跨级组件通信:
可以使用provide/inject来向下传递数据,或者使用 p a r e n t / parent/ parent/root来向上查找父级组件。非父子组件通信:
可以使用事件总线(Event Bus)或者Vuex来实现非父子组件之间的通信。事件总线是一个空的Vue实例,可以用来触发和监听事件。Vuex是一个状态管理库,可以将数据集中管理,实现组件之间的共享状态。
45、你了解vue的diff算法
吗?说说看?
Vue的diff算法是一种
高效的虚拟DOM比较算法
,用于计算前后两个虚拟DOM树之间的差异,并将差异应用到真实的DOM上,以达到最小化DOM操作的目的
。
Vue的diff算法采用了双端比较的策略,即同时从新旧虚拟DOM树的头部和尾部开始比较,以尽可能地减少比较次数。
具体来说,Vue的diff算法分为以下几个步骤:
- 首先比较新旧虚拟DOM树的根节点,如果节点类型不同,则直接替换整个节点;如果节点类型相同,则进入下一步比较。
- 比较节点的属性和事件,如果有变化,则更新节点的属性和事件。
- 比较节点的子节点,如果子节点数量不同,则直接替换整个节点的子节点;如果子节点数量相同,则进入下一步比较。
- 对于相同位置的子节点,递归执行上述步骤,直到所有子节点都比较完毕。
- 对于新虚拟DOM树中多余的节点,直接添加到真实DOM中;对于旧虚拟DOM树中多余的节点,直接从真实DOM中删除。
通过以上步骤,Vue的diff算法可以高效地计算出前后两个虚拟DOM树之间的差异,并将差异应用到真实的DOM上,以达到最小化DOM操作的目的。
46、简单说一下 Virtual Dom
?
1、Virtual Dom 是一种
将页面的状态抽象成一个虚拟的 DOM 树的技术
。它是 React 和 Vue 等前端框架的核心技术之一。
2、Virtual Dom 的工作原理是,当页面状态发生变化时,框架会先将新的状态转换成一个新的虚拟 DOM 树,然后将这个新的虚拟 DOM 树与旧的虚拟 DOM 树进行比较,找出两者之间的差异,最后只更新需要更新的部分,从而避免了不必要的 DOM 操作,提高了页面的性能。
3、使用 Virtual Dom 的好处是,它可以让开发者专注于页面的状态管理,而不需要关心页面的具体实现细节。同时,由于 Virtual Dom 可以减少 DOM 操作,因此可以提高页面的性能和响应速度。
47、Vue3.0 所采用的 Composition Api
与Vue2.x 使用的 Options Api
有什么不同?
Vue3.0 所采用的 Composition Api 与 Vue2.x 使用的 Options Api 有以下不同:
- 组织代码的方式不同:Composition Api 是基于函数的,而 Options Api 是基于对象的。
- 可复用性更强:Composition Api 可以更好地实现逻辑复用,可以将逻辑代码封装成函数,方便在多个组件中复用。
- 更好的类型推断:Composition Api 可以更好地支持 TypeScript,因为它使用了更多的类型推断。
- 更好的代码可读性:Composition Api 可以更好地组织代码,使代码更加清晰易读,减少了 Options Api 中的混乱和重复。
- 更好的响应式:Composition Api 中的 reactive 和 ref 可以更好地处理响应式数据,使得代码更加简洁易懂。
总之,Composition Api 在代码组织、可复用性、类型推断、代码可读性和响应式等方面都有很大的优势,可以更好地帮助开发者构建高质量的 Vue 应用程序。
48、说说 React中的setState执行机制
?
在 React 中,setState 是用来更新组件状态的方法。当调用 setState 方法时,React 会将新的状态对象合并到当前状态对象中,然后重新渲染组件。
具体的执行机制如下:
- 调用 setState 方法时,React 会将新的状态对象添加到一个更新队列中。
- 如果在同一个事件循环中多次调用 setState 方法,React 会将这些更新合并成一个更新,只执行一次更新操作。
- 在组件生命周期函数和事件处理函数中调用 setState 方法时,React 会将更新添加到队列中,并在当前事件循环结束后执行更新操作。
- 在异步操作中调用 setState 方法时,React 会将更新添加到队列中,并在下一个事件循环中执行更新操作。
- 在更新操作执行前,React 会对更新队列进行优化,去除重复的更新和无效的更新,以提高性能。
总之,React 的 setState 方法是一个异步操作,它会将更新添加到队列中,并在合适的时机执行更新操作。在使用 setState 方法时,需要注意避免出现死循环和不必要的更新,以提高组件的性能。
49、说说对React中类组件
和函数组件
的理解?有什么区别?
1、类组件和函数组件都是用来
定义组件
的一种方式。
2、类组件是使用ES6中的class语法来定义的,必须继承React.Component类,并且必须实现render的方法来返回组件的jsx;类组件可以使用state和生命周期方法来管理组件的状态和行为
3、函数组件使用函数来定义的,它们只需要返回JSX即可,函数组件不能使用state和生命周期方法,但是可以使用React Hook来管理组件的状态和行为
区别:
- 语法:类组件使用class语法,函数组件使用函数语法。
- 状态管理:类组件可以使用state来管理组件的状态,而函数组件需要使用React Hooks来管理状态。
- 生命周期:类组件有生命周期方法,如componentDidMount()和componentWillUnmount()等,而函数组件没有生命周期方法。
- 性能:函数组件通常比类组件更轻量级,因为它们不需要继承React.Component类和实现render()方法。但是,如果需要管理状态和行为,函数组件可能需要使用React Hooks,这可能会影响性能。
50、说说对React Hooks
的理解?解决了什么问题?
React Hooks 是 React 16.8 中引入的新特性,它可以让我们在不编写 class 的情况下使用 state 和其他 React 特性。
React Hooks 解决了以下问题:
- 在组件之间复用状态逻辑很难。React Hooks 提供了一种方式来共享状态逻辑,称为自定义 Hook。
- 复杂组件变得难以理解。React Hooks 可以将组件拆分成更小的函数,每个函数只关注一个特定的功能。
- Class 组件中的生命周期方法和状态逻辑之间的关系不直观。React Hooks 可以将生命周期方法和状态逻辑分离,使代码更易于理解和维护。
- Class 组件中的 this 绑定问题。React Hooks 中的函数组件没有 this 绑定问题,使代码更加简洁和易于维护。
总之,React Hooks 提供了一种更简单、更直观的方式来编写 React 组件,使代码更易于理解和维护。
51、UseMemo
和useCallback
如何提升了性能,应用场景有哪些?
UseMemo和useCallback都可以用来
优化React组件的性能。
UseMemo
可以缓存计算结果,避免重复计算,从而提高组件的渲染性能。
它的应用场景
包括:
- 计算开销较大的值,例如从API获取数据并进行复杂的计算。
- 优化子组件的渲染,避免不必要的渲染。
- 避免在每次渲染时都创建新的对象或数组。
UseCallback
可以缓存函数,避免在每次渲染时都创建新的函数,从而提高组件的渲染性能。
它的应用场景
包括:- 将函数作为props传递给子组件时,避免子组件不必要的渲染。
- 在使用useEffect时,避免因为函数引用变化而导致useEffect重复执行。
- 在使用useMemo时,避免因为函数引用变化而导致useMemo重复计算。
52、Vue-router
的实现原理是什么?
Vue-router是Vue.js官方提供的
路由管理插件。
它的实现原理
主要包括以下几个方面:
- 基于Vue.js的组件化开发思想,将路由规则抽象成一个个组件,通过组件的嵌套和切换来实现页面的跳转和刷新。
- 利用HTML5的History API,通过pushState和replaceState方法来改变浏览器的URL地址,从而实现前端路由的跳转和刷新。
- 利用Vue.js的响应式数据绑定机制,将路由信息存储在Vue实例的data属性中,通过watch监听路由变化,从而实现路由的动态更新和响应。
- 利用Vue.js的生命周期钩子函数,如beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave等,来实现路由的拦截和控制,从而实现路由的权限管理和页面的动态加载。
总之,Vue-router的实现原理是基于Vue.js的组件化开发思想和响应式数据绑定机制,利用HTML5的History API和Vue.js的生命周期钩子函数来实现前端路由的跳转、刷新、拦截和控制。
53、如何封装组件在不同的项目之间使用
如何实现?
要封装组件以便在不同的项目中使用,可以按照以下步骤进行:
- 创建一个独立的组件库项目,该项目包含所有要封装的组件。
- 在组件库项目中,为每个组件创建一个独立的文件夹,并在其中包含组件的所有代码和样式。
- 在每个组件文件夹中,创建一个
index.js
文件,该文件将导出组件的所有必要内容,例如组件类、样式和其他依赖项。- 在组件库项目中,使用打包工具(例如 webpack)将所有组件打包到一个单独的 JavaScript 文件中。
- 将组件库项目发布到 npm 或其他包管理器中,以便其他项目可以使用它。
- 在其他项目中,使用
npm install
命令安装组件库。- 在需要使用组件的文件中,导入所需的组件并使用它们。
54、vue、react、angular
区别?
Vue、React、Angular 都是
现代化的 JavaScript 框架
,用于构建单页应用程序(SPA)和动态 Web 应用程序。
它们之间的区别如下:
- Vue.js 是一种轻量级的框架,易于学习和使用,适合小型项目。React.js 是一个库,提供了更多的灵活性和可定制性,适合大型项目。Angular 是一个完整的框架,提供了许多功能和工具,适合大型企业级项目。
- Vue.js 的模板语法更加简单和直观,易于理解和维护。React.js 使用 JSX 语法,需要更多的学习和理解。Angular 使用 HTML 和 TypeScript,需要更多的学习和掌握。
- Vue.js 的性能比较好,因为它使用了虚拟 DOM 和异步渲染。React.js 也使用了虚拟 DOM,但是需要手动优化性能。Angular 的性能相对较差,因为它使用了双向数据绑定和大量的依赖注入。
- Vue.js 和 React.js 都是开源的,社区活跃,有大量的插件和组件可用。Angular 也是开源的,但是由于其复杂性和学习曲线,社区相对较小。
55、说说你对Redux
的理解?其工作原理
?
Redux是一个JavaScript
状态管理库
,它可以帮助我们在应用程序中管理和更新状态。Redux的核心概念是store,它是一个包含整个应用程序状态的JavaScript对象。Redux通过使用action和reducer来更新store中的状态。
当应用程序中的某个事件发生时,我们可以创建一个action对象,它描述了这个事件的类型和相关的数据。然后,我们将这个action对象传递给一个reducer函数,它会根据action的类型来更新store中的状态。reducer函数接收当前的状态和action对象作为参数,并返回一个新的状态对象。
Redux的工作原理可以概括为以下几个步骤:
- 创建一个store对象,它包含整个应用程序的状态。
- 定义action对象,它描述了应用程序中的事件。
- 创建reducer函数,它根据action的类型来更新store中的状态。
- 将action对象传递给reducer函数,它会返回一个新的状态对象。
- 更新store中的状态,使其与新的状态对象匹配。
- 在应用程序中订阅store的变化,以便在状态发生变化时更新UI。
Redux的优点
是可以帮助我们更好地组织和管理应用程序的状态,使得应用程序更加可预测和可维护。同时,Redux还可以与React等框架和库进行集成,使得我们可以更方便地使用它来管理应用程序的状态。
第一次周考2205A
56、说说对盒子模型
的理解?
盒子模型是指在网页中,
每个元素都被看作是一个矩形的盒子,这个盒子由四个边框、内边距、外边距和内容区域组成
。这个模型可以帮助我们更好地理解和控制网页中元素的布局和样式。
具体来说,盒子模型包括以下几个部分:
内容区域(content)
:元素的实际内容,例如文本、图片等。内边距(padding)
:内容区域与边框之间的空白区域,可以通过设置 padding 属性来控制。边框(border)
:包围内容区域和内边距的线条,可以通过设置 border 属性来控制。外边距(margin)
:边框与相邻元素之间的空白区域,可以通过设置 margin 属性来控制。
在实际应用中,我们可以通过设置盒子模型的各个属性来控制元素的大小、位置、边框样式、背景颜色等。同时,盒子模型也是 CSS 布局的基础,通过合理地使用盒子模型,我们可以实现各种复杂的布局效果。
57、Css的选择器
有哪些?优先级
?哪些可以继承?
CSS的选择器有以下几种:
- 元素选择器(element selector):通过元素名称来选择元素,如p、div、a等。
- 类选择器(class selector):通过类名来选择元素,以“.”开头,如.class。
- ID选择器(ID selector):通过ID来选择元素,以“#”开头,如#id。
- 属性选择器(attribute selector):通过元素的属性来选择元素,如[type=“text”]。
- 伪类选择器(pseudo-class selector):通过元素的状态来选择元素,如:hover、:active、:visited等。
- 伪元素选择器(pseudo-element selector):用于选择元素的某个部分,如::before、::after等。
CSS选择器的优先级从高到低依次为:
- !important
- 行内样式(style属性)
- ID选择器
- 类选择器、属性选择器、伪类选择器
- 元素选择器、伪元素选择器
可以继承的CSS属性有以下几种:
- 字体系列属性(font-family、font-size、font-weight等)
- 文本系列属性(text-align、text-indent、text-decoration等)
- 颜色属性(color、background-color等)
- 列表属性(list-style-type、list-style-image等)
- 表格布局属性(border-collapse、border-spacing等)
- 其他属性(visibility、cursor等)
58、元素水平垂直居中
的方法有哪些?如果元素不定宽高呢?
元素水平垂直居中的方法有以下几种:
- 使用flex布局:将父元素设置为display: flex;,并设置justify-content: center;和align-items: center;即可实现水平垂直居中。
- 使用绝对定位:将父元素设置为相对定位,子元素设置为绝对定位,并设置top: 50%;和left: 50%;,再使用transform: translate(-50%, -50%);即可实现水平垂直居中。
- 使用表格布局:将父元素设置为display: table;,子元素设置为display: table-cell;,并设置vertical-align: middle;和text-align: center;即可实现水平垂直居中。
如果元素不定宽高,可以使用以下方法:
- 使用flex布局:将父元素设置为display: flex;,并设置justify-content: center;和align-items: center;,子元素设置为flex: 1;即可实现水平垂直居中。
- 使用绝对定位:将父元素设置为相对定位,子元素设置为绝对定位,并设置top: 50%;和left: 50%;,再使用transform: translate(-50%, -50%);和max-width: 100%;和max-height: 100%;即可实现水平垂直居中
- 使用表格布局:将父元素设置为display: table;,子元素设置为display: table-cell;,并设置vertical-align: middle;和text-align: center;,再使用max-width: 100%;和max-height: 100%;即可实现水平垂直居中。
59、怎么理解回流
跟重绘
?什么场景下会触发?
回流(reflow)和重绘(repaint)是
浏览器渲染页面时的两个重要概念
。
回流
指的是当页面中的元素发生位置、大小等属性的变化时,浏览器需要重新计算元素的位置和大小,然后重新布局整个页面,这个过程就是回流。回流会导致页面的重新渲染,因此会比较耗费性能。
重绘
指的是当页面中的元素的样式属性发生变化时,浏览器只需要重新绘制这些元素的样式,而不需要重新计算元素的位置和大小,这个过程就是重绘。重绘的性能消耗比回流要小。
在以下场景下会触发回流和重绘:
- 当页面首次加载时,浏览器需要进行回流和重绘。
- 当页面中的元素的位置、大小、内容等属性发生变化时,会触发回流和重绘。
- 当页面中的元素的样式属性发生变化时,会触发重绘。
- 当浏览器窗口大小发生变化时,会触发回流和重绘。
- 当页面滚动时,会触发重绘。
因此,在编写页面时,应该尽量避免频繁的回流和重绘,
可以通过以下方式来优化页面性能:
- 使用 CSS3 的 transform 和 opacity 属性来实现动画效果,避免使用 position 和 float 等属性。
- 使用 position: absolute 或 fixed 来定位元素,避免使用 margin 和 padding 等属性。
- 避免频繁修改 DOM 元素的样式属性,可以将多个修改操作合并成一次操作。
- 使用虚拟列表等技术来优化大量数据的渲染。
60、什么是响应式设计
?响应式设计的基本原理
是什么?如何做?
响应式设计是一种
网页设计方法
,可以使网站在不同设备上(如桌面电脑、平板电脑、手机等)呈现出最佳的用户体验。响应式设计的基本原理是通过使用CSS媒体查询和弹性网格布局等技术,根据不同设备的屏幕大小和分辨率,自动调整网页的布局、字体大小、图片大小等元素,以适应不同设备的屏幕大小和分辨率。
要做好响应式设计,需要遵循以下几个步骤:
- 设计弹性网格布局:使用相对单位(如百分比、em等)来定义网页元素的大小和位置,以适应不同设备的屏幕大小。
- 使用CSS媒体查询:根据不同设备的屏幕大小和分辨率,使用CSS媒体查询来调整网页的布局、字体大小、图片大小等元素。
- 优化图片大小:使用适当的图片格式和压缩技术来减小图片的大小,以提高网页加载速度。
- 测试和优化:在不同设备上测试网页的响应式设计效果,并根据测试结果进行优化,以提高用户体验。
61、说一下对盒子模型
的理解?
1、盒子模型就是指的在网页中,
每个元素都被看做是一个矩形的盒子
,包含了内容、内边距、边框和外边距四个部分,其中,内容区域是元素实际显示内容的区域,内边距是内容区域与边框之间的距离,边框是围绕内容和内边距的线条,外边距是边框与相邻元素之间的距离。2、盒子模型的大小由元素的高度和宽度属性决定,但是实际大小还要加上内边距、边框和外边距的值,在css中,可以通过box-sizing属性来控制盒子模型的计算方式。有两种取值:content-box和border-box。content-box表示盒子模型的大小只包括内容区域,而border-box表示盒子模型的大小包括内容区域、内边距和边框,但不包括外边距。
3、盒子模型在网页布局中非常重要,可以通过设置元素的宽度、高度、内边距、边框和外边距等属性来实现各种布局效果。同时,盒子模型还可以通过CSS的定位属性来控制元素的位置和层级关系。
62、如何让一个盒子水平垂直居中
,有哪些方法?
使用flex布局
,将父容器设置为display:flex,然后使用justify-content:center和align-items:center来实现水平垂直居中- 使用绝对定位,将盒子的left和top属性设置为50%,然后使用transform:translate(-50%,-50%)来实现水平垂直居中。
- 使用表格布局,将父容器设置为display:table,然后将盒子设置为display:table-cell,使用vertical-align:middle和text-align:center来实现水平垂直居中。
63、说说JavaScript
有哪些数据类型
,如何存储?
JavaScript有七种数据类型
,分别是:
基本数据类型
:Number、String、Boolean、Null、Undefined、Symbol(ES6新增)。引用数据类型
:Object。- 基本数据类型的值存储在栈内存中,而引用数据类型的值存储在堆内存中,栈内存中存储的是指向堆内存中实际数据的指针。
- 当我们创建一个基本数据类型的变量时,会在栈内存中分配一段空间,将值存储在这个空间中;
- 当我们创建一个引用数据类型的变量时,会在栈内存中分配一段空间,这个空间中存储的是指向堆内存中实际数据的指针,而实际数据存储在堆内存中。
64、如何理解响应式
?实现的方法有哪些?有什么区别?
1、响应式网站合计是
一种网络页面设计布局,页面设计与开发应当根据用户的行为以及设备环境(系统平台、屏幕尺寸、屏幕定向等)进行相应的响应和调整
2、
媒体查询:
使用@media可以根据不同的屏幕尺寸来定义不同的样式3、
百分比:
相对于包含块的计量单位,通过对属性设置百分比来适应不同的屏幕4、
vw/vh:
视口单位,可以根据浏览器的窗口大小来进行适配5、
rem:
指相对于根元素的字体大小的单位,rem只是一个相对单位
65、Css性能优化
有哪些常见的方法,具体如何实现?
1、避免过度的约束
2、避免后代选择符
3、使用紧凑的语法
4、避免不必要的命名空间
5、避免不必要的重复
6、最好使用表示语义的名字来进行定义
7、避免!important,可以选择其他的选择器
8、尽可能的精简规则,可以合并不同类的重复规则
66、判断数据类型
的方法有哪些?有什么区别?
1、
**typeof :**
a. 可以判断数据类型,它返回表示数据类型的字符串,返回的结果只能包括number,Boolean,string,function,object,undefined
b. 可以使用typeof判断变量是否存在
c. typeof运算符的问题是无论引用的对象是什么类型,它都返回object
2、
**instanceof方法:**
般用来检测引用数据类型,表达式为:A instanceof B,判断A是否是B的实例,如果 A 是 B 的实例,则返回 true,否则返回 false,由构造类型判断出数据类型
3、
**constructor方法:**
constructor是prototype对象上的属性,指向构造函数,
4、
**无敌万能的方法:jquery.type()**
如果对象是undefined或null,则返回相应的“undefined”或“null”。
如果对象有一个内部的[[Class]]和一个浏览器的内置对象的 [[Class]] 相同,我们返回相应的 [[Class]] 名字
67、Bind 、Call 、Apply有什么区别?如何实现一个bind方法?
1、
call
、apply
、bind
作用是改变函数执行时的上下文,简而言之就是改变函数运行时的this
指向2、
apply
接受两个参数,第一个参数是this
的指向,第二个参数是函数接受的参数,以数组的形式传入,改变this
指向后原函数会立即执行,且此方法只是临时改变this
指向一次3、
call
方法的第一个参数也是this
的指向,后面传入的是一个参数列表,跟apply
一样,改变this
指向后原函数会立即执行,且此方法只是临时改变this
指向一次,当第一个参数为null
、undefined
的时候,默认指向window
(在浏览器中)4、bind方法和call很相似,第一参数也是
this
的指向,后面传入的也是一个参数列表(但是这个参数列表可以分多次传入),改变this
指向后不会立即执行,而是返回一个永久改变this
指向的函数5、区别:
- 三者都可以改变函数的
this
对象指向- 三者第一个参数都是
this
要指向的对象,如果如果没有这个参数或参数为undefined
或null
,则默认指向全局window
- 三者都可以传参,但是
apply
是数组,而call
是参数列表,且apply
和call
是一次性传入参数,而bind
可以分为多次传入bind
是返回绑定this之后的函数,apply
、call
则是立即执行
- 修改
this
指向 - 动态传递参数
// 方式一:只在bind中传递函数参数
fn.bind(obj,1,2)()
// 方式二:在bind中传递函数参数,也在返回函数中传递参数
fn.bind(obj,1)(2)
- 兼容
new
关键字
整体实现代码如下:
Function.prototype.myBind = function (context) {
// 判断调用对象是否为函数
if (typeof this !== "function") {
throw new TypeError("Error");
}
// 获取参数
const args = [...arguments].slice(1),
fn = this;
return function Fn() {
// 根据调用方式,传入不同绑定值
return fn.apply(this instanceof Fn ? new fn(...arguments) : context, args.concat(...arguments));
}
}
68、如何理解闭包
?闭包的应用场景
是?
1、一个函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起(或者说函数被引用包围),这样的组合就是闭包(closure),也就是说,闭包让你可以在一个内层函数中访问到其外层函数的作用域
2、应用场景:
- 创建私有变量、
- 延长变量的生命周期
- 缓存数据
- 实现回调函数
69、简单的说一下什么是事件代理
?
1、事件代理(Event Delegation),又称之为事件委托。
是JavaScript中常用绑定事件的常用技巧
。顾名思义,“事件代理”即是把原本需要绑定在子元素的响应事件(click、keydown…)委托给父元素,让父元素担当事件监听的职务。事件代理的原理是DOM元素的事件冒泡。
70、什么是防抖
和节流
?有什么区别?如何实现?
1、防抖是当事件被触发后,延迟
n
秒后再执行回调,如果在这n
秒内事件又被触发,则重新计时。2、节流就是 n 秒后在执行该事件,若在 n 秒内被重复触发,则重新计时,可以减少一段时间内事件的触发频率。
3、区别:
相同点:
都可以通过使用
setTimeout
实现目的都是,降低回调执行频率。节省计算资源.
不同点:
函数防抖,在一段连续操作结束后,处理回调,利用
clearTimeout
和setTimeout
实现。函数节流,在一段连续操作中,每一段时间只执行一次,频率较高的事件中使用来提高性能函数防抖关注一定时间连续触发的事件,只在最后执行一次,而函数节流一段时间内只执行一次
例如,都设置时间频率为500ms,在2秒时间内,频繁触发函数,节流,每隔 500ms 就执行一次。防抖,则不管调动多少次方法,在2s后,只会执行一次
4、
**应用场景:**
防抖在连续的事件,只需触发一次回调的场景有:
- 搜索框搜索输入。只需用户最后一次输入完,再发送请求
- 手机号、邮箱验证输入检测
- 窗口大小
resize
。只需窗口调整完成后,计算窗口大小。防止重复渲染。节流在间隔一段时间执行一次回调的场景有:
- 滚动加载,加载更多或滚到底部监听
- 搜索框,搜索联想功能
71、说说你对作用域链
的理解?
1、在当前作用域中查找所需变量,但是
该作用域没有
这个变量,那这个变量就是自由变量
。如果在自己作用域找不到
该变量就去父级作用域查
找,依次向上级作用域
查找,直到访问到window对象就被终止,这一层层的关系就是作用域链。
2、作用域链的作用是保证对执行环境有权访问的所有变量和函数的有序访问,通过作用域链,可以访问到外层环境的变量和函数。作用域链的本质上是一个指向变量对象的指针列表。变量对象是一个包含了执行环境中所有变量和函数的对象。作用域链的前端始终都是当前执行上下文的变量对象。
72、说说对原型
和原型链
的理解?
1、
**原型:**
- JS声明构造函数(用来实例化对象的函数)时,会在内存中创建一个对应的对象,这个对象就是原函数的原型。构造函数默认有一个prototype属性,prototype的值指向函数的原型。同时原型中也有一个constructor属性,constructor的值指向函数对象。
- 通过构造函数实例化出来的对象,并不具有prototype属性,其默认有一个__proto__属性,__proto__的值指向构造函数的原型。在原型对象上添加或修改的属性,在所有实例化出的对象上都可共享。
- 作用:数据共享、节约内存空间;实现继承
2、
**原型链**:
- 当在实例化的对象中访问一个属性时,首先会在该对象内部(自身属性)寻找,如找不到,则会向其__proto__指向的原型中寻找,如仍找不到,则继续向原型中__proto__指向的上级原型中寻找,直至找到或Object.prototype.__proto__为止(值为null),这种链状过程即为原型链。
- 作用:查找对象的属性方法
73、vue的生命周期
和含义有哪些?
1、vue的生命周期就是指从开始创建、初始化数据、编译模板、挂在DOM和渲染、更新渲染、卸载的一系列过程
2、
beforeCreate():
创建前,在new一个vue实例后,只有一些默认的生命周期钩子和默认事件,其他的东西都还没创建。在此生命周期执行的时候,data和methods中的数据都还没有初始化。不能在这个阶段使用data中的数据和methods中的方法3、
created():
被创建,data 和 methods都已经被初始化好了,可以调用了4、
BeforeMount():
挂载前,在内存中已经编译好了模板了,但是还没有挂载到页面中,此时,页面还是旧的5
、mounted():
已挂载,Vue实例已经初始化完成了。此时组件脱离了创建阶段,进入到了运行阶段。 如果我们想要通过插件操作页面上的DOM节点,最早可以在和这个阶段中进行6、
beforeupdate():
更新前,页面中的显示的数据还是旧的,data中的数据是更新后的, 页面还没有和最新的数据保持同步7、
updated():
更新,页面显示的数据和data中的数据已经保持同步了,都是最新的8、
beforeDestory():
销毁前,Vue实例从运行阶段进入到了销毁阶段,这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于可用状态。还没有真正被销毁9、
Destoryed():
被销毁,Vue实例从运行阶段进入到了销毁阶段,这个时候上所有的 data 和 methods , 指令, 过滤器 ……都是处于可用状态。还没有真正被销毁
74、vue自定义指令的钩子函数
有哪些?
bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。但是你可以通过比较更新前后的值来忽略不必要的模板更新 (详细的钩子函数参数见下)。
componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
unbind:只调用一次,指令与元素解绑时调用。
75、JavaScript本地存储有哪些?区别和使用场景?
1、
javaScript
本地缓存的方法我们主要讲述以下四种:
- cookie
- sessionStorage
- localStorage
- indexedDB
2、关于
cookie
、sessionStorage
、localStorage
三者的区别主要如下:
- 存储大小:
cookie
数据大小不能超过4k
,sessionStorage
和localStorage
虽然也有存储大小的限制,但比cookie
大得多,可以达到5M或更大- 有效时间:
localStorage
存储持久数据,浏览器关闭后数据不丢失除非主动删除数据;sessionStorage
数据在当前浏览器窗口关闭后自动删除;cookie
设置的cookie
过期时间之前一直有效,即使窗口或浏览器关闭- 数据与服务器之间的交互方式,
cookie
的数据会自动的传递到服务器,服务器端也可以写cookie
到客户端;sessionStorage
和localStorage
不会自动把数据发给服务器,仅在本地保存3、针对不对场景的使用选择:
- 标记用户与跟踪用户行为的情况,推荐使用
cookie
- 适合长期保存在本地的数据(令牌),推荐使用
localStorage
- 敏感账号一次性登录,推荐使用
sessionStorage
- 存储大量数据的情况、在线文档(富文本编辑器)保存编辑历史的情况,推荐使用
indexedDB
月考111
76、说说你对递归
的理解?封装一个方法用递归实现树形结构封装?
1、递归是一种算法或者函数的实现方式,他通过调用自身来解决问题。在递归的过程中,每次调用都会将问题分解为更小的子问题,直到问题被分解为足够小的部分,可以直接求解
2、递归通常可以用来解决具有递归结构的问题,比如像树形结构和图形结构等。
77、Link
和@import
有什么区别?
1、Link和@import都是用于引入外部资源的方法,但是也有所区别
区别:
1、加载时间:Link标签在页面加载时同时进行加载;@import是在页面加载完毕后再进行加载。
2、兼容性:Link标签是HTML标签,兼容性比较好;@import是css语法,不兼容旧版本的浏览器。
3、作用范围:Link标签可以引入各种类型的文件,比如CSS、JS、图片等;而@import只能引入CSS文件
4、权重:Link标签引入的CSS文件的权重高于@import引入的CSS文件,因此在样式进行冲突的时候,Link标签引入的样式会覆盖@import引入的样式
78、什么是FOUC
?如何避免?
1、FOUC是文档样式暂时失效,指的是在网页加载时,由于CSS文件未能及时加载,导致页面出现短暂的样式化内容的现象。
如何避免:
1、将CSS文件放在HTML文档的头部,这样可以确保CSS文件在页面加载时首先被加载
2、使用内联CSS样式,将CSS样式直接嵌入HTML文档中,这样可以避免CSS问价加载时的延迟。
3、使用CSS预处理器,比如Sass和Less,可以将CSS文件编译为单个CSS文件,从而减少HTTP请求量
4、使用浏览器缓存,将CSS缓存到本地,可以减少页面的加载时间
5、使用JavaScript可以在页面加载时检测CSS文件是否已经加载完成,如果加载未完成,则可以延迟页面的渲染,直到CSS文件加载完成
79、说说你对预编译器
的理解?
1、预编译器就是一种程序,它在编译源代码之前对源代码进行处理,它可以执行一些预处理的操作,例如宏替换、条件编译、头文件包含等。预编译器是编译器的一部分,他可以在编译的过程中自动执行,也可以通过命令进行执行
2、预编译器的主要作用是
将源代码中的宏定义替换为实际的代码,以及将头文件中的内容插入到源代码中
。这样可以减少代码的重复性,提高代码的可读性和可维护性。3、预编译器还可以进行条件编译,根据不同的条件编译选项生成不同的代码。这样可以根据不同的需求生成不同的代码,提高代码的灵活性和可移植性。
80、shouldcomponentUpdate
的作用?
1、shouldComponentUpdate是React生命周期方法之一,用于控制组件是否需要重新渲染。它的作用是在组件重新渲染之前,判断组件的props和state是否发生了变化,如果没有变化则返回false,否则返回true,告诉React需要重新渲染组件。
2、 使用shouldComponentUpdate可以提高React应用的性能,因为它可以避免不必要的重新渲染。当组件的props或state发生变化时,React会重新渲染组件,如果组件的props或state没有变化,那么重新渲染是没有必要的,这时候就可以使用shouldComponentUpdate来避免不必要的重新渲染。
81、概述React中的事务处理逻辑?
React中的事务处理逻辑是指在React组件的生命周期中,React会自动创建一个事务对象,用于管理组件的更新过程。事务对象包含了一系列的生命周期钩子函数,用于在组件更新过程中执行特定的操作。
82、React组件的划分业务组件/技术组件
?
1、React组件可以根据其功能和用途划分为业务组件和技术组件。
2、
业务组件
是指与业务相关的组件,例如登录框、购物车、商品列表等。这些组件通常是具有特定功能的,可以被多个页面或应用程序共享。业务组件通常是由多个技术组件组成的,例如表单、按钮、列表等。3、
技术组件
是指与技术相关的组件,例如表单、按钮、列表等。这些组件通常是具有通用功能的,可以被多个业务组件共享。技术组件通常是由HTML、CSS和JavaScript代码组成的,可以通过props和state属性进行交互。
83、React性能优化
是哪个周期函数?
React性能优化是在
shouldComponentUpdate生命周期函数
中进行的。该函数在组件更新前被调用,可以通过返回false来阻止组件的重新渲染,从而提高应用的性能。在该函数中,可以通过比较前后两次的props和state来决定是否需要重新渲染组件。
84、说说对于Fiber架构
的理解和应用场景?
1、Fiber架构是一种
基于协程的轻量级并发模型,它可以在单个线程中实现高并发的处理能力。
2、Fiber架构的核心思想是将一个长时间的任务分解成多个小任务,然后在这些小任务之间进行切换,从而实现并发处理。
Fiber架构的应用场景主要包括以下几个方面:
- 高并发的网络应用:Fiber架构可以在单个线程中处理大量的网络请求,从而提高应用的并发处理能力。
- 高性能的数据库访问:Fiber架构可以在单个线程中处理多个数据库请求,从而提高数据库访问的性能。
- 大规模的数据处理:Fiber架构可以将大规模的数据处理任务分解成多个小任务,从而提高数据处理的效率。
- 实时数据处理:Fiber架构可以实现实时数据处理,例如实时监控、实时日志处理等。
85、React性能优化
的方案?
使用PureComponent或shouldComponentUpdate:
PureComponent是React提供的一个优化性能的组件,它会自动进行浅比较,如果props和state没有变化,就不会重新渲染组件。如果使用的是普通的Component,可以手动实现shouldComponentUpdate方法,进行自定义的比较逻辑。使用React.memo:
React.memo是React提供的一个高阶组件,它可以缓存组件的渲染结果,如果props没有变化,就直接返回缓存的结果,不会重新渲染组件。避免在render方法中进行复杂的计算和操作
:render方法会在每次组件更新时被调用,如果在其中进行复杂的计算和操作,会影响组件的性能。可以将这些计算和操作放到组件的生命周期方法中,或者使用memoization技术进行缓存。使用React.lazy和Suspense:
React.lazy是React提供的一个懒加载组件的方式,可以将组件的加载延迟到需要使用时再进行。Suspense是React提供的一个组件,可以在组件加载时显示一个loading状态,等待组件加载完成后再显示组件。使用shouldComponentUpdate和React.memo进行性能测试:
可以使用React的性能测试工具进行测试,找出哪些组件需要进行优化,然后使用shouldComponentUpdate或React.memo进行优化。使用React的Profiler工具进行性能分析
:React提供了一个Profiler工具,可以帮助开发者分析组件的渲染性能,找出哪些组件需要进行优化。
86、简述flux和css渲染
的过程是什么?
Flux是一种架构模式,
用于构建可扩展的Web应用程序。它的核心思想是单向数据流,即数据只能从一个地方流向另一个地方,这样可以避免数据的混乱和不一致。
CSS渲染的过程是将HTML文档和CSS样式表结合起来,生成可视化的Web页面。具体过程如下:
- 浏览器解析HTML文档,构建DOM树。
- 浏览器解析CSS样式表,构建CSSOM树。
- 将DOM树和CSSOM树结合起来,生成渲染树。
- 根据渲染树中的节点信息,计算每个节点的位置和大小。
- 将渲染树中的节点绘制到屏幕上,生成最终的Web页面。
87、说一下DOM0、DOM2、DOM3
事件处理的区别是什么?
DOM0、DOM2、DOM3是指不同版本的JavaScript DOM(文档对象模型)事件处理规范。
1、DOM0事件处理:在DOM0事件处理中,事件处理程序直接赋值给DOM元素的属性
2、DOM2事件处理:DOM2事件处理规范引入了addEventListener()和removeEventListener()方法,这些方法允许在同一元素上添加多个事件处理程序。
3、DOM3事件处理:DOM3事件处理规范引入了更多的事件类型和更多的事件处理程序选项。
88、如何判断页面滚动到底部,如何判断页面中元素是否进入可视化区域?
判断页面滚动到底部可以通过以下方式:
- 获取页面的滚动高度scrollTop、页面可视高度clientHeight和页面总高度scrollHeight。
- 判断scrollTop + clientHeight是否等于scrollHeight,如果相等则表示页面已经滚动到底部。
判断页面中元素是否进入可视化区域可以通过以下方式:
1.获取元素的位置信息,包括元素的offsetTop、offsetLeft、offsetWidth和offsetHeight。
- 获取页面的滚动高度scrollTop和页面可视高度clientHeight。
- 判断元素的位置信息是否在scrollTop和scrollTop + clientHeight之间,如果在则表示元素已经进入可视化区域。
89、说一下浏览器Event Loop
和nodejs中Event Loop
的区别?
1、浏览器Event Loop和nodejs中Event Loop的主要区别在于它们的实现方式和运行环境。
2、 浏览器Event Loop是基于单线程的JavaScript引擎实现的,它负责处理JavaScript代码的执行和事件的处理。
3、浏览器中的Event Loop主要包括宏任务和微任务两种类型的任务队列。宏任务包括setTimeout、setInterval、DOM事件等,而微任务包括Promise、MutationObserver等。在每次事件循环中,先执行所有的微任务,然后执行一个宏任务,然后再执行所有的微任务,如此循环往复。
4、 而nodejs中的Event Loop是基于多线程的C++实现的,它负责处理JavaScript代码的执行和I/O操作的处理。
5、nodejs中的Event Loop主要包括六个阶段:timers、pending callbacks、idle、prepare、poll和check。在每个阶段中,Event Loop会执行相应的任务队列,直到所有任务都被执行完毕。
90、说一下vue-router的底层实现原理
?
1、Vue-router的底层实现原理主要是基于Vue.js的响应式系统和路由的hash模式或history模式。
2、在Vue.js中,每个组件都有一个响应式的状态对象,当状态发生变化时,Vue.js会自动更新视图。Vue-router利用这个特性,将路由信息存储在一个响应式的状态对象中,当路由发生变化时,Vue.js会自动更新视图。
3、 在hash模式下,Vue-router监听浏览器的hashchange事件,当hash发生变化时,Vue-router会根据新的hash值更新路由状态对象,并触发视图更新。
4、 在history模式下,Vue-router使用HTML5的history API,通过pushState和replaceState方法改变浏览器的URL,同时更新路由状态对象,并触发视图更新。
5、为了防止用户手动修改URL导致路由状态对象和视图不一致,Vue-router还使用了popstate事件监听浏览器的后退和前进操作,以便及时更新路由状态对象和视图。
6、除此之外,Vue-router还提供了路由守卫、动态路由、嵌套路由等功能,这些功能的实现也是基于Vue.js的响应式系统和路由模式的特性。
91、说一下vuex的实现原理
?commit
和dispatch
方法是如何实现的?
1、Vuex是一个状态管理库,它的实现原理是基于Vue.js的响应式系统和单向数据流模式。
2、Vuex将应用程序的状态存储在一个中央存储库中,称为store。组件可以通过getter和mutation访问和修改store中的状态,而action可以用于异步操作。
4、commit方法是用于提交mutation的方法,它接收两个参数:mutation的名称和payload(可选)。当调用commit方法时,Vuex会在store中查找对应的mutation并执行它,从而修改store中的状态。
5、 dispatch方法是用于触发action的方法,它接收两个参数:action的名称和payload(可选)。当调用dispatch方法时,Vuex会在store中查找对应的action并执行它,从而触发异步操作或其他一些副作用。
92、有A,B,C 三个组件,A组件跳转到B组件缓存,A组件跳转到C组件不缓存,如何实现?
1、可以在路由配置中使用
<keep-alive>
标签来实现组件缓存。2、在路由配置中,将需要缓存的组件包裹在
<keep-alive>
标签中,并设置include
属性为需要缓存的组件名称3、在组件中,通过
activated
和deactivated
生命周期钩子来判断是否需要缓存。如果需要缓存,则在activated
钩子中设置$route.meta.keepAlive
为true
,在deactivated
钩子中设置为false
4、 在跳转时,根据需要缓存的组件名称来判断是否需要缓存。如果需要缓存,则在跳转时设置
$route.meta.keepAlive
为true
,否则设置为false
专高六第二周
93、对于MVVM
的理解?
1、MVVM是一种
软件架构模式
,它将应用程序分为三个部分:模型Model、视图View、视图模型ModelView。其中,模型表示应用程序的数据和业务逻辑,视图表示用户界面,视图模型就是连接模型和视图的中间件。2、在MVVM中,视图模型负责将模型中的数据转换为视图可以使用的格式,并将视图中的用户操作转换为模型可以理解的模式,视图模型还负责处理视图和模型之间的通信,比如像数据绑定、命令绑定等。
3、
MVVM的优点?
1、分离关注点:将应用程序的数据和业务逻辑与用户界面分离,使得代码更加清晰易懂。
2、可测试性:由于视图模型与视图和模型之间的通信是通过数据绑定和命令绑定实现的,因此可以更加容易的对视图模型进行单元测试。
3、可维护性:由于MVVM将应用程序分为三个部分,因此可以更加容易的对应用程序进行维护和扩展。
94、请详细说一下对于vue生命周期
的理解?
vue生命周期指的是
vue实例从创建到销毁的整个过程
,vue生命周期分为八个阶段:1、beforeCreate:在实例被创建之前调用,此时实例的数据和方法都还未初始化,无法访问data、computed、methods等属性。
2、created:在实例创建完成后调用,此时实例的数据和方法已经初始化完成,但是DOM还未渲染,无法访问DOM元素。
3、 beforeMount:在DOM挂载之前调用,此时模板已经编译完成,但是还未将其挂载到页面上。
4、 mounted:在DOM挂载完成后调用,此时实例已经挂载到页面上,可以访问DOM元素。
5、 beforeUpdate:在数据更新之前调用,此时数据已经更新,但是DOM还未重新渲染。
6、updated:在数据更新完成后调用,此时数据已经更新,DOM也已经重新渲染完成。
7、beforeDestroy:在实例销毁之前调用,此时实例还未销毁,可以进行一些清理工作。
8、 destroyed:在实例销毁之后调用,此时实例已经销毁,无法访问实例的数据和方法。
95、vue组件之间的数据传递方式
有哪些?
Vue组件之间的数据传递方式有以下几种:
- 父子组件传递数据:父组件通过props向子组件传递数据,子组件通过$emit触发事件向父组件传递数据。
- 兄弟组件传递数据:可以通过一个共同的父组件作为中介,将数据传递给兄弟组件。
- 使用Vuex进行数据管理:Vuex是Vue的状态管理库,可以将数据存储在全局的store中,各个组件可以通过getter和mutation来获取和修改数据。
- 使用事件总线进行数据传递:可以使用Vue实例作为事件总线,通过 o n 和 on和 on和emit方法来进行组件之间的数据传递。
- 使用provide和inject进行数据传递:父组件通过provide向子组件提供数据,子组件通过inject注入数据。
- 使用 r e f s 进行数据传递:可以通过 refs进行数据传递:可以通过 refs进行数据传递:可以通过refs获取到子组件的实例,从而直接访问子组件的数据和方法。
96、vue的路由实现:hash模式和history模式原理
?
UE的路由实现主要有两种模式:hash模式和history模式。
- hash模式 在hash模式下,URL中的#符号后面的内容被称为hash值,它不会被发送到服务器,而是在客户端进行处理。当URL中的hash值发生变化时,浏览器会触发hashchange事件,我们可以通过监听该事件来实现路由的切换。
- 例如,当我们访问http://example.com/#/home时,浏览器会将#后面的内容作为hash值,即/home。当我们点击页面上的链接切换到另一个路由时,实际上是修改了URL中的hash值,而不是发送一个新的请求。
- history模式 在history模式下,URL中不再需要#符号,而是直接使用正常的URL路径。
- 当我们访问http://example.com/home时,浏览器会向服务器发送一个请求,服务器会返回对应的页面内容。当我们点击页面上的链接切换到另一个路由时,实际上是使用了HTML5的history API,通过pushState或replaceState方法修改了浏览器的历史记录,同时也修改了URL路径。
97、vue路由的钩子函数
有哪些?
Vue路由的钩子函数包括:
- beforeEach(to, from, next):在路由跳转之前执行,可以用来进行全局的路由拦截和权限控制。
- afterEach(to, from):在路由跳转之后执行,可以用来进行页面的统计和日志记录等操作。
- beforeRouteEnter(to, from, next):在进入路由之前执行,可以用来进行异步数据的获取和页面的初始化等操作。
- beforeRouteUpdate(to, from, next):在当前路由更新时执行,可以用来进行组件的更新和数据的同步等操作。
- beforeRouteLeave(to, from, next):在离开当前路由之前执行,可以用来进行数据的保存和页面的确认等操作。
98、v-if
和v-show
的区别?
v-if和v-show都是用来控制元素的显示与隐藏
1、v-if是根据表达式的值来决定是否渲染元素,如果表达式的值为false,则元素不会被渲染到页面中,如果表达式的值为true,则元素会被渲染到页面中。
2、v-if在切换时有较高的切换性能开销,因为它会在每次切换时重新渲染元素及其子组件。 v-show也是根据表达式的值来决定元素是否显示
3、但是不同的是,v-show只是控制元素的CSS属性display的值,如果表达式的值为false,则元素的display属性被设置为none,元素仍然存在于DOM中,如果表达式的值为true,则元素的display属性被设置为原来的值,元素仍然存在于DOM中。
4、v-show在切换时没有额外的性能开销,因为元素始终存在于DOM中,只是控制其显示与隐藏。
99、$route
和$router
的区别?
r o u t e 和 route和 route和router都是Vue.js中的路由相关对象,但是它们的作用和使用方式有所不同。
- $route是Vue.js中的路由信息对象,它包含了当前路由的一些信息,比如路由路径、参数、查询参数等。
- r o u t e 对象可以在组件中通过 t h i s . route对象可以在组件中通过this. route对象可以在组件中通过this.route访问到。
- $router是Vue.js中的路由实例对象,它负责管理路由的跳转和导航。
- r o u t e r 对象可以在组件中通过 t h i s . router对象可以在组件中通过this. router对象可以在组件中通过this.router访问到。通过$router对象,我们可以进行路由的跳转、导航等操作。
100、如何让CSS只在当前组件中起作用
?
CSS模块化
使用CSS模块化,可以将CSS文件与组件文件分离,每个组件都有自己的CSS文件,这样可以避免CSS样式的冲突,在React中,可以使用CSS Modules库来实现CSS模块化。使用CSS Modules的步骤如下
: 1. 在组件文件中引入CSS文件,并将CSS文件名改为“文件名.module.css”。 2. 在组件中使用CSS类名时,需要使用“styles.类名”来引用。在组件中使用样式
使用less文件,只需要保证最外层容器类名不相同就可以了
101、<keep-alive></keep-alive>
的作用是什么?
<keep-alive></keep-alive>
是Vue.js中的一个内置组件,它的作用是用来缓存组件实例,以避免重复渲染和销毁。- 当一个组件被包裹在
<keep-alive></keep-alive>
标签中时,它不会被销毁,而是被缓存起来,直到它被再次使用。- 这样可以提高应用程序的性能,因为不需要每次重新渲染和初始化组件。
- 在使用
<keep-alive></keep-alive>
时,可以通过设置include
和exclude
属性来控制哪些组件需要缓存,哪些不需要。
102、在vue中使用插件
的步骤?
在Vue中使用插件的步骤如下:
- 安装插件:使用npm或yarn等包管理工具安装需要的插件。
- 引入插件:在Vue项目的入口文件(如main.js)中引入插件。
- 注册插件:使用Vue.use()方法注册插件。
- 使用插件:在Vue组件中使用插件提供的功能。
103、请列举出三个vue中常见的生命周期钩子函数
?
- created:在实例创建完成后被立即调用,可以在这个阶段进行数据的初始化和方法的定义等操作。
- mounted:在实例挂载到DOM元素上后被立即调用,可以在这个阶段进行DOM操作和异步请求等操作。
- updated:当数据发生变化时,组件会重新渲染,此时updated钩子函数会被调用,可以在这个阶段进行DOM操作和数据更新等操作。
104、什么是Vue SSR
?
- vue SSR是指在服务器端将vue组件渲染成HTML字符串,然后将其发送到浏览器端进行展示的过程。
2.优点
- 更好的SEO:由于搜索引擎爬虫无法执行JavaScript,因此传统的客户端渲染对SEO不友好。而SSR可以在服务器端生成完整的HTML页面,有利于搜索引擎的爬取和索引。
- 更快的首屏加载速度:传统的客户端渲染需要先下载JavaScript文件,然后再进行渲染,这会导致首屏加载速度较慢。而SSR可以在服务器端生成完整的HTML页面,减少了客户端渲染的时间,从而提高了首屏加载速度。
- 更好的用户体验:由于SSR可以在服务器端生成完整的HTML页面,因此用户可以更快地看到页面内容,减少了等待时间,提高了用户体验
105、Proxy
相比于definedProperty
的优势?
1、
更加灵活:
proxy可以代理整个对象,而不是像defined Property只能代理对象的某个属性,这就使得proxy更加的灵活,可以处理更多的场景2、
更加强大:
proxy可以拦截更多的操作,比如像函数的调用、构造函数等,而defined Property只能拦截对象属性的读写操作3、
更加直观:
proxy的api更加直观,易于理解和使用,而defined Property的api比较复杂,需要更深入的了解对象的内部机制4、
更加安全:
proxy可以防止一些常见的安全漏洞,比如对象属性被篡改,对象属性被删除等,而defined Property无法完全的解决这些问题5、
更加高效:
proxy的性能比defined Property更好,因为proxy可以在底层实现中进行优化,而defined Property的实现比较复杂,性能相对较差
106、vuex是什么
?怎么使用?哪种功能场景使用它?
vuex是一个专门为
vuejs设计的状态管理库
,它可以集中管理vue应用中的所有组件的状态,vuex的核心概念包括state、mutation、getters、actions、modulesstate:存储应用的状态数据,可以通过this.$store.state访问。
- mutations:用于修改state中的数据,只能进行同步操作,可以通过this.$store.commit()方法调用。
- actions:用于处理异步操作,可以通过this.$store.dispatch()方法调用。
- getters:用于从state中派生出一些状态,可以通过this.$store.getters访问。
- modules:将应用的状态分割成多个模块,每个模块都有自己的state、mutations、actions和getters
使用Vuex需要先在Vue应用中安装它,可以通过npm或者CDN方式引入。然后在Vue应用中创建一个store对象,将state、mutations、actions、getters和modules等配置项传入,最后在Vue实例中将store对象注入到Vue实例中即可。
使用Vuex的场景包括: - 应用中有多个组件需要共享状态数据。 - 应用中有复杂的状态逻辑,需要集中管理。 - 应用中有大量的异步操作,需要统一管理。
107、vue2.x响应式原理
?
- vue2.x的响应式原理是通过数据劫持和发布订阅模式来进行实现
- 数据劫持:Vue2.x通过Object.defineProperty()方法来实现数据劫持,即在数据被访问或修改时,能够触发相应的操作。在Vue2.x中,每个组件实例都有一个对应的Watcher实例,当组件中的数据发生变化时,Watcher实例会通知组件进行重新渲染。
- 发布订阅模式:Vue2.x中使用了发布订阅模式来实现数据的响应式。在Vue2.x中,每个组件实例都有一个对应的Dep实例,用于存储Watcher实例。当组件中的数据发生变化时,Dep实例会通知所有的Watcher实例进行更新。
4.具体实现流程如下:
- 在Vue2.x中,通过Object.defineProperty()方法来实现数据劫持,即在数据被访问或修改时,能够触发相应的操作。
- 在组件实例创建时,会对组件中的所有数据进行遍历,为每个数据创建一个对应的Dep实例,并将该数据的所有Watcher实例存储到Dep实例中。
- 当组件中的数据发生变化时,会触发对应数据的setter方法,setter方法会通知该数据对应的Dep实例进行更新。
- Dep实例会遍历存储在其中的所有Watcher实例,并通知它们进行更新。 5. Watcher实例接收到更新通知后,会触发组件的重新渲染。
108、ES5、ES6和ES2015
有什么区别?
- ES5是ECMAScript 5的缩写,是JavaScript的第五个版本,于2009年发布。
- ES6是ECMAScript 6的缩写,也称为ES2015,是JavaScript的第六个版本,于2015年发布。
- ES6相对于ES5来说,增加了很多新的语法和特性,包括箭头函数、let和const关键字、模板字符串、解构赋值、类和模块等。
- 这些新特性使得JavaScript更加现代化、易读易写、可维护性更高。
- ES2015是ES6的另一个名称,因为在发布时,ECMAScript委员会决定将ES6更名为ES2015,以反映其发布年份。从ES2015开始,ECMAScript每年都会发布一个新版本,因此ES6也可以看作是ES2015的第一个版本。
109、let
有什么作用,有了var
为什么还要使用let?
- let和var都是用来声明变量的关键字,但它们有一些不同之处。
- 作用域:使用var声明的变量是函数作用域或全局作用域,而使用let声明的变量是块级作用域。块级作用域指的是在if语句、for循环、函数等花括号内部声明的变量只在该花括号内部有效。
- 变量提升:使用var声明的变量会发生变量提升,即变量可以在声明之前使用,但是值为undefined。而使用let声明的变量不会发生变量提升,即在声明之前使用会报错。
- 重复声明:使用var声明的变量可以重复声明,后面的声明会覆盖前面的声明。而使用let声明的变量在同一作用域内不能重复声明。
110、举一些ES6对于String字符串做的常用升级优化
?
- 模板字符串:使用反引号(`)来创建字符串模板,可以在其中插入变量或表达式,更加方便易读。
- 字符串扩展方法:ES6提供了许多新的字符串方法,如startsWith()、endsWith()、includes()、repeat()等,使字符串的操作更加方便。
- 解构赋值:可以使用解构赋值来将字符串拆分成单个字符或子串,更加灵活。
- 字符串的遍历器接口:ES6为字符串添加了遍历器接口,可以使用for…of循环遍历字符串中的每个字符。
- Unicode支持:ES6支持Unicode字符集,可以使用\u或\u{}来表示Unicode字符,同时也提供了一些新的Unicode相关方法,如codePointAt()、String.fromCodePoint()等。
- 正则表达式升级:ES6对正则表达式进行了升级,添加了u修饰符,支持处理Unicode字符,同时也提供了新的正则表达式方法,如sticky、flags等。
111、举一些ES6对于Array数组类型做的常用升级优化
?
- 扩展运算符(Spread Operator):可以将一个数组展开成多个参数,或者将多个参数组合成一个数组。
- Array.from()方法:可以将类数组对象或可迭代对象转换成数组。
- Array.of()方法:可以将一组值转换成数组。
- find()和findIndex()方法:可以在数组中查找符合条件的元素,并返回它的值或索引。
- includes()方法:可以判断数组中是否包含某个元素。
- fill()方法:可以用指定的值填充数组中的所有元素。
- flat()和flatMap()方法:可以将嵌套的数组展开成一维数组,并对每个元素执行指定的操作。
- reduce()方法的初始值参数:可以指定reduce()方法的初始值,避免空数组时出现错误。
- 箭头函数和forEach()方法:可以简化数组的遍历操作。 10. map()、filter()和reduce()方法的返回值:可以链式调用这些方法,使代码更加简洁易读。