侧边栏壁纸

前端知识体系

2023年08月17日 516阅读 0评论 0点赞

前端知识体系

HTML:

如何理解HTML语义化?
1,让人更容易读懂(增加代码可读性)
2,让搜索引擎更容易读懂(SEO)

哪些标签是块级元素、哪些是内联元素?
1,display:block/table;div h1 h2 table ul ol p等
2,display:inline/inline-block; span img input button等

CSS:

盒子模型的宽度如何计算
offsetWidth=(内容宽度+内边距+边框),无外边距
box-sizing: border-box;

margin的纵向重叠问题
相邻元素的margin-top和margin-bottom会发生重叠
空白内容标签也会重叠

margin的负值问题
margin-top和margin-left负值,元素会向上、向左移动
margin-right负值,右侧元素左移,自身不受影响
margin-bottom负值,下方元素上移,自身不受影响

BFC的理解和应用
块级格式化上下文
一块独立渲染区域,内部元素的渲染不会影响边界以外的元素

形成BFC的常见条件:
1,float不是none
2,position是absolute或者fixed
3,overflew不是visible
4,display是flex inline-block等

BFC可以用来清除浮动
float布局的问题,以及clearfix(清除浮动)
1,圣杯布局和双飞翼布局

 使用float布局

两侧使用margin负值,以便和中间内容横向重叠
防止中间内容被两侧覆盖,一个用padding一个用margin

position

手写clear fix
flex
flex-direction: 主轴的方向
justify-content:主轴对齐方式
align-items:
flex-wrap:
align-self:
absolute和relative分别依据什么定位
absolute: 依据最近一层的定位元素定位
relative: 依据自身定位

居中对齐有哪些实现方式

水平居中:
inline元素:text-align:center
block元素:margin:auto
absolute元素:left:50%+margin-left负值

垂直居中:
inline元素:line-height的值等于height的值
absolute元素:top:50%+margin-top负值
absolute元素:transform(-50%,-50%)
absolute元素:top,left,bottom,right=0+margin:auto

line-height的继承问题
写具体数值,如20px,则继承该值
写比例,如2或1.5,则继承该比例
写百分比,如200%,则继承计算出来的值

rem是什么
rem:相对长度单位,相对于根元素
px:绝对长度单位
em:相对长度单位,相对于父元素

如何实现响应式
media-query:根据不同的屏幕宽度设置根元素的font-size
rem,基于根元素的相对单位
flex弹性布局
百分比布局

JS基础

值类型
undefined
string
number
boolean
symbol

引用类型
object

数组
null
function
typeof

识别所有值类型
识别function
判断是否是引用类型,不可再细分 typeof null === 'object'
100=='100' true
0=='' true
0==false true
false=='' true
null==undefinded

强制类型转换: parseInt、parseFloat、toString等

隐式类型: if、逻辑运算、==、+拼接字符串

原型和原型链:
每个class都有显示原型prototype
每个实例都有隐式原型 proto
实例的 proto 指向对应class的prototype

闭包:
作用域应用的特殊情况,有两种表现:
函数作为参数被传递
函数作为返回值被返回
所有自由变量的查找,是在函数定义的地方,不是在函数执行的地方

this:
作为普通函数被调用 返回window
使用call apply bind 返回传入的值
作为对象方法被调用 返回的是当前对象本身
在class方法中被调用 返回的是当前实例
箭头函数 this取上级作用域的
在函数执行的地方确定,不是在函数定义的地方确定
模拟bind函数
闭包的实际应用
隐藏数据
自执行函数
异步和单线程
E
vent Loop:
同步代码,一行一行放在Call Stack中执行
遇到异步会先记录下来,等到时机(定时、网络请求等)
时机到了,就移动到Callback Queue中
如果Call Stack为空(即同步代码执行完) Event Loop开始工作
轮询查找Callback Queue,如果有则移动到Call Stack中执行
然后继续轮询查找
DOM事件也是基于Event Loop实现的

Promise:

三种状态
pending
resolved
rejected

状态的表现和变化
pending状态,不会触发then和catch
resolved状态,会触发后续的then回调函数
rejected状态,会触发后续的catch回调函数
then和catch对状态的影响
then正常返回resolved,里面有报错则返回rejected
catch正常返回resolved,里面有报错则返回rejected

async/await:
执行async函数,返回的是Promise对象
await相当于Promise的then
try...catch可捕获异常,代替了Promise的catch

异步的本质:

for...of:
执行异步时,顺序执行

宏任务和微任务:
宏任务:setTimeout、setInterval、Ajax、DOM事件
微任务:Promise、async/await
微任务执行时机比宏任务要早
宏任务在DOM渲染后触发
微任务在DOM渲染前触发
Event Loop和DOM渲染
每次Call Stack清空(即每次轮询结束),即同步任务执行完
都是DOM重新渲染的机会,DOM结构如果有改变则重新渲染
然后再去触发下一次Event Loop
描述Event Loop的机制
初始化promise时,传入的函数会立刻被执行

web API:

DOM:
对现有节点进行appChild()操作,会移动现有节点

BOM:
navigator(浏览器信息):
screen(屏幕信息):
location(地址信息):
history(浏览历史信息):
通用的事件监听函数
描述事件冒泡的流程
基于DOM树形结构
事件会顺着触发元素向上冒泡
event.stopPropagation():阻止事件冒泡
J
SONP:
可绕过跨域限制
服务器可以任意动态拼接数据返回
所以,就可以获得跨域的数据,只要服务端愿意返回

存储:

cookie:
存储大小,最大4Kb
http请求时需要发送到服务端,增加请求数据量
localStorage
数据会永久存储,除非代码或者手动删除

sessionStorage:
只存在于当前会话,浏览器关闭则清空

http:

http状态码:
1xx:服务器收到请求
2xx:请求成功
3xx:重定向
4xx:客户端错误
5xx:服务端错误
200:成功
301:永久重定向
302:临时重定向
304:资源未被修改
404:资源未找到
403:没有权限
500:服务器错误
504:网关超时

Restful API:

传统API设计:把每个url当做一个功能
Restful API:把每个url当做一个唯一的资源

http headers:
Request headers:
Accept:浏览器可接收的数据格式
Accept-Encoding:浏览器可接收的压缩算法,如gzip
Accept-Languange:浏览器可接收的语言,如zh-CN
Connection:keep-alive一次TCP连接重复使用
cookie:

host:
User-Agent:浏览器信息
Content-type:发送数据的格式,如application/json
Response headers:
Content-type:返回数据的格式,如application/json
Content-length:返回数据的大小,多少字节
Content-Encoding:返回数据的压缩算法,如gzip
set-cookie:
Cache-Control:

max-age:缓存的过期时间
no-cache:不使用强制缓存
no-store:不使用强制缓存也不使用服务器端缓存

自定义header

http的缓存机制:

缓存策略:
Cache-Control:
response-headers中
控制强制缓存的逻辑
Cache-Control:max-age=31536000

强制缓存:
初次请求,服务器返回资源和Cache-Control
浏览器缓存返回数据到本地缓存中
再次请求时,判断Cache-Control是否过期
没有过期,直接从本地缓存中获取请求数据

协商缓存(对比缓存):
服务端缓存策略
服务端判断客户端资源,是否和服务端资源一样
一致则返回304,否则返回200和最新的资源
初次请求,服务端返回资源和资源标识
再次请求,带着资源标识
服务端返回304或者返回新的资源和资源标识

资源标识:
在Response-Headers中,有两种
Last-Modified资源的最后修改时间
Etag资源的唯一标识,字符串

Last-Modified:
初次请求,服务端返回资源和Last-Modified
浏览器再次请求,Response-Headers带着If-Modified-Since
服务端返回304或返回资源和新的Last-Modified

Etag:
初次请求,服务端返回资源和Etag
浏览器再次请求,Response-Headers带着If-None-Match
服务端返回304或返回资源和新的Etag
会优先使用Etag,Last-Modified只能精确到秒级
如果资源被重复生成,而内容不变,则Etag更精确
刷新操作方式,对缓存的影响:
正常操作:地址栏输入url,跳转链接,前进后退等

强制缓存有效,协商缓存有效

手动刷新:F5,点击刷新按钮,右击菜单刷新

强制缓存失效,协商缓存有效

强制刷新: ctrl+F5

 强制缓存失效,协商缓存失效

页面的加载过程:
从输入url到渲染页面的整个过程

请求过程:
DNS解析:域名->IP地址
浏览器根据IP地址向服务器发起http请求
服务器处理http请求,并返回给浏览器

渲染过程:
根据HTML代码生成DOM Tree
根据CSS代码生成CSSOM
将DOM Tree和CSSOM整合形成Render Tree
根据Render Tree渲染页面
如果遇到则暂停渲染,优先加载并执行JS代码,完成之后再进行渲染
直至把Render Tree渲染完成
window.onload和DOMContentLoaded的区别
window.onload:页面的全部资源加载完才会执行,包括图片、视频等
DOMContentLoaded:DOM渲染完即可执行,此时图片、视频等资源还没有加载完

性能优化:

原则:
多使用内存、缓存或其他方法
减少CPU计算量,减少网络加载耗时

方法:
减少资源体积:压缩代码
减少访问次数:合并代码,SSR服务器渲染,缓存
使用更快的网络:CDN加速
CSS放在head,JS放在body最下面
尽早开始执行JS,在DOMContentLoaded触发
懒加载
对DOM查询进行缓存
频繁DOM操作,合并到一起插入DOM结构
节流throttle、防抖debounce

防抖:

节流:

安全:

XSS跨站请求攻击:
替换特殊字符,

XSRF跨站请求伪造:
使用post接口
增加各种验证方式

Vue2原理:

组件化:
MVVM模型:数据驱动视图
传统组件,只是静态渲染,更新依赖于操作DOM

响应式原理:
vue2:核心API:Object.defineProperty
监听数组:重新定义数组原型
监听复杂对象:深度监听需要递归到底,一次性计算量大
新增属性和删除属性监听不到,所以才有Vue.set、Vue.delete

vue3: proxy
缺点: 兼容性不好,无法使用polyfill
vdom:
dom操作非常耗时和消耗性能
vdom:用js模拟dom结构,计算出最小变更,操作dom
h函数:生成vnode结构
patch函数: 更新dom
render函数: 渲染

diff算法:
树的diff算法的时间复杂度是 O(n*3)
只比较同一层级,不跨级比较。
tag不同,直接删掉重建,不再深度比较。
tag和key,两者都相同,则认为是相同节点,不再深度比较。

 模板编译: patch:更新操作
       with语法
   vue template complier将模板编译成render函数

执行render函数生成vnode,基于vnode可以执行patch和diff

使用webpack vue-loader,会在开发环境下编译模板

初次渲染过程:
1,解析模板为render函数,在开发环境中已经完成,vue-loader
2,触发响应式,监听data属性的getter和setter
3,执行render函数,生成vnode,patch(element,vnode),执行render函数会触发getter

更新过程:
1,修改data,触发setter
2,执行render函数,生成newVnode
3,patch(vnode,newVnode)

路由:
hash:
hash变化会触发网页跳转,即浏览器的前进、后退
hash变化不会刷新页面,SPA必需的特点
hash永远不会提交到服务端

history:
用url规范的路由,但跳转时不刷新页面
history.pushState
window.onpopstate
为什么在v-for中使用key
diff算法中通过tag和key来判断是否是同一节点
减少渲染次数,提高渲染性能

描述Vue组件的生命周期(父子组件):
父 created

子created
子mounted
父mounted
父 beforeUpdated
子beforeUpdated
子updated
父updated

Vue组件的通讯:
父子组件props和this.$emit
自定义事件event.$on event.$off event.$emit

vuex
描述组件的渲染和更新过程
双向数据绑定v-model的实现原理
input元素的value=this.name
绑定input事件this.name=$event.target.value
data更新触发重新渲染 (re-render)

computed有什么特点:
缓存,data不变不会重新计算
提高性能
组件data为什么必须是一个函数
组件实际上是一个类,每个用到组件的地方都是在对类进行实例化,如果data不是一个函数,那么在调用修改的过程中会影响到其他使用同一组件的地方。

请求应该放在哪个生命周期里
mounted
如何将组件的所有props传递给子组件
$props
v-bind="$props"
什么时候使用异步组件
加载大组件
路由异步加载
什么时候使用keep-alive
缓存组件,不需要重复渲染
比如多个静态tab页的切换

优化性能
什么时候需要使用beforeDestory
解绑自定义事件event.$off
清除定时器
解绑自定义的DOM事件

Vuex中action和mutation的区别
action中可以处理异步,mutation不可以
mutation做原子操作,一次只能做一个操作。
action可以整合多个mutation

Vue如何监听数组变化
Object.defineProperty不能监听数组变化。
重新定义原型,重写push pop等方法,实现监听。
Proxy可以原生支持监听数组变化
Vue为什么是异步渲染,$nextTick有什么用
异步渲染(以及合并data修改),以提高渲染性能
$nextTick在DOM渲染之后触发

常见性能优化的方式
合理使用v-show和v-if
合理使用computed
v-for时加key,避免和v-if同时使用。
自定义事件、DOM事件要及时销毁。
合理使用异步组件、keep-alive
data层级不要太深
使用vue-loader在开发环境做预编译

Vue3

vue3比vue2有什么优势
性能更好
体积更小
更好的ts支持
更好的代码组织
更好的逻辑抽离

Vue3的生命周期

Options API生命周期
跟vue2相比,beforeDestroy改为beforeUnmount
destroyed改为unmouted
其他沿用Vue2的生命周期
beforeCreate
组件实例被创建之前
created
组件实例已经完全创建
beforeMount
组件挂载之前
mounted
组件挂载到实例上之后
beforeUpdate
组件数据发生变化,更新之前
updated
组件数据更新之后
beforeDestroy
组件实例销毁之前
destroyed
组件实例销毁之后
activated
keep-alive 缓存的组件激活时
deactivated
keep-alive 缓存的组件停用时调用
errorCaptured
捕获一个来自子孙组件的错误时被调用
Composition API生命周期
setup 等于beforeCreate和created
ref toRef
toRef不能用于普通对象,只能用于响应式对象
toRef(state,'name')
toRefs:合成函数返回响应式对象

ref是一个对象(不丢失响应式),value存储值
通过.value属性的get和set实现响应式  
 用于模板、reactive时不需要.value
 computed返回的是一个类似于ref的对象,也有.value

为什么需要toRef和toRefs

不丢失响应式的情况下,把对象数据分解/扩散
前提是针对下响应式对象(reactive封装的)非普通对象

最佳使用方式
用reactive做对象的响应式,用ref做值类型响应式
setup中返回toRefs(state),或者返回toRef(state,'name')
ref的命名xxxRef
合成函数返回响应式对象时,使用toRefs

Vue3升级了哪些功能?
createApp:
emits属性:
生命周期
多事件:
Fragment:
template中可以有多个节点
移除.sync:
异步组件的写法:
移除filter:
Teleport:
Suspense:
Composition API
Composition API实现逻辑复用:
抽离逻辑代码到一个函数中
函数命名约定为useXXX格式
在setup中引用useXXX函数

Vue3如何实现响应式:
深度监听,性能更好
可监听新增/删除属性
可监听数组变化
无法兼容所有浏览器,无法使用polifll

watch和watchEffect的区别:
两者都可以监听data属性变化
watch需要明确监听的属性
watchEffect会根据其中的属性,自动监听其变化
watchEffect初始化时一定会执行一次,收集要监听的数据

setup中如何获取组件的实例
在setup和其他Composition API中没有this
可通过getCurrentInstance获取当前实例

Vue3为什么比Vue2快

Proxy响应式
PatchFlag(静态标记):
编译模板时,动态节点做标记
标记,分为不同的类型,例如TEXT PROPS
diff算法时,可以区分静态节点和动态节点,以及不同类型的动态节点
在线地址:vue-next-template-explorer.netlify.app/#
diff算法比较
hoistStatic 静态提升
将静态节点的定义,提升到父作用域,缓存起来
多个相邻的静态节点,会被合并起来
拿空间换时间
cacheHandler
SSR优化
静态节点直接输出,绕过了vdom
动态节点还是需要动态渲染
tree-shaking
编译时根据不同的情况,引入不同的API

Vite
在开发环境下使用ES6 Module,无需打包
在生产环境下使用rollup

webpack和babel
基本配置
拆分配置和merge
拆分不同环境的配置文件,把公共配置放在common中

ES6处理
样式处理:

  图片引入

高级配置
多入口
抽离、压缩 css
抽离公共代码
懒加载
module、 chunk、 bundle的区别
module:各个源码文件,webpack中一切皆模块
chunk:多模块合并成的,如:entry import() splitChunk
bundle:最终的输出文件

优化打包效率
优化babel-loader (可用于生产环境)
IgnorePlugin 避免引入无用模块 (可用于生产环境)
IgnorePlugin直接不引入,代码中没有
noParse (可用于生产环境)
noParse引入,但是不打包
happyPack (可用于生产环境)

多进程打包
ParallelUglifyPlugin (可用于生产环境)
自动刷新
热更新
DllPlugin 动态链接库插件
优化产出代码
体积更小
合理分包,不重复加载
速度更快、内存使用更少
1,小图片base64编码
2,bundle加hash
3,懒加载
4,提取公共代码
5,IgnorePlugin
6,使用CDN加速
7,使用production
自动开启压缩
自动删除调试代码

启用Tree-Shaking :
ES6 Module静态引入,编译时引入
Commonjs动态引入,执行时引入
只有ES6 Module才能静态分析,实现Tree-Shaking
8,Scope Hosting 多函数合并
代码体积更小
创建函数作用域更少
代码可读性更好
babel
babel-polyfill:会污染全局变量
babel-runtime:
前端为何要进行打包和构架
体积更小(Tree-Shaking、压缩、合并),加载更快
编译高级语言或语法(TS、ES6+、模块化、SCSS)
兼容性和错误检查(Polyfill、postcss、eslint)

git
常用命令
git add . :提交所有修改文件
git checkout xxx:签出或者还原
git commit -m xxx:提交
git push origin master
git pull orgin master
git branch:查看所有分支
git checkout -b xxx: 切换分支
git merge xxx: 合并分支

面试题

    split()和join的区别:

split:拆分数组 '1-2-3'.split('-') // [1,2,3]
join:数组拼接成字符串 [1,2,3].join('-') // 1-2-3
数组 pop、push、unshift、shift的作用
pop、push、unshift、shift、splice都是非纯函数
pop:返回被移出的最后一项
shift:返回被移出的第一项
push:返回修改后的数组长度
unshift:返回修改后的数组长度

数组slice和splice的区别:
slice相当于对数组进行拷贝截取
splice:

数组有哪些纯函数:
纯函数:不改变原数组,返回一个新数组
concat、map、filter、slice
call和apply的区别:

jsonp原理:
浏览器的同源策略(服务器没有同源策略)和跨域
函数声明和函数表达式的区别:
函数声明function fn(){......}
函数表达式 const fn=function(){...}
函数声明会在代码执行前预加载,而函数表达式不会
new Object()和Object.create()的区别:
new Object()等同于{},原型Object.prototype
Object.create(null) ,没有原型
Object.create({...}) 可以指定原型

手写trim方法,保证兼容性
手写数组flatern:

 节流和防抖:

防抖(debounce):防止抖动,先执行着,什么时候停止操作了,再执行下一步
节流(throttle):限制执行次数,多次密集的触发只执行一次

箭头函数:

箭头函数有什么缺点:
1,没有arguments
2,无法通过apply、call、bind改变this的指向
什么时候不能使用箭头函数:
不适用于对象的方法
不适用于原型方法
不适用于构造函数
不适用于动态上下文中的回调函数

Vue生命周期和methods

for……in和for……of的区别:
遍历对象: for……in可以,for……of不可以
遍历Map Set:for……of可以,for……in不可以
遍历generator:for……of可以,for……in不可以
for……in用于可枚举数据,如对象、数组、字符串
for……of用于可迭代数据:如数组、字符串、Map、Set
for await……of有什么用
用于遍历多个promise
Vue组件通讯有几种方式
props和$emit

自定义事件
$attr
$parent
$refs
provide/inject

Vuex
JS严格模式有什么特点
'use strict' // 全局开启严格模式
function fn(){
'use strict' // 某个函数开启
}

特点:
全局变量必须先声明
如果一个网页访问慢,你该如何分析问题原因

首屏优化:
路由懒加载,优先保证首页加载
服务端渲染SSR
APP预取
分页,上拉加载更多
图片懒加载
Hybird

Vue应该如何监听JS报错

1,   window.onerror
2, errorCaptured生命周期: 监听所有下级组件的错误,返回false会组织向上传播
3,errorHander   app.config.errorHander
 errorCaptured监听一些重要、有风险组件的错误
  window.onerror和errorHander   候补全局监听

Vue优化
v-if 和v-show合理使用
keep-alive缓存组件
v-for使用key
异步组件、路由懒加载
computed缓存数据
SSR

网页加载速度慢:
优化服务端硬件配置,使用CND加速
路由懒加载,大组件异步加载——减少主包的体积
优化HTTP缓存策略

网页渲染慢:
优化服务端接口
优化前端组件内部逻辑
服务端渲染SSR

技术深度
js内存泄漏如何检测,场景有哪些?
垃圾回收机制:标记清除
被全局变量、函数引用,组件销毁时未清除
被全局事件、定时器引用,组件销毁时未清除
被自定义事件引用,组件销毁时未清除
浏览器和nodejs的事件循环有什么区别?
浏览器中js执行和dom渲染共用一个线程
浏览器和nodejs的event loop流程基本相同
nodejs宏任务和微任务分类型,有优先级

遍历数组,for和foreach哪个更快?

 for更快,foreach每次都要创建一个函数来调用,而for不会创建函数

Vue每个生命周期都做了什么?
beforeCreate:
创建一个空白的Vue实例,data、method尚未被初始化,不可使用
created:
Vue实例初始化完成,完成响应式绑定,data、method都已经初始化完成,可调用,
尚未开始渲染模板
beforeMount:
编译模板,调用render函数生成vdom,还没开始渲染DOM
mounted:
完成DOM渲染,组件创建完成,开始由“创建阶段”进入“运行阶段”
beforeUpdate:
data发生变化之后,准备更新DOM(尚未更新DOM)
updated:
data发生变化,且DOM更新完成
不要再updated中修改data,可能会导致死循环
beforeUnmount:
组件进入销毁阶段(尚未销毁,可正常使用)
可移除、解绑一些全局事件、自定义事件
unMounted:
组件被销毁了,所有的子组件也都被销毁了

llezbn0l.png

0
打赏

—— 评论区 ——

昵称
邮箱
网址
取消
博主栏壁纸
107 文章数
15 标签数
403 评论量
舔狗日记