学习内容
1月1日
水平垂直居中方案
1. flex居中
2. 绝对定位+margin auto居中
3. 绝对定位+Transform居中
隐藏元素
1. display:none
2. opacity:0
3. visibility:hidden
typeof与instanceof
1. typeof识别所有的值类型,识别函数,能区分是否是引用类型
2. instanceof用于检测构造函数的prototype 属性是否出现在某个实例对象的原型链上
数组的方法及作用
1. forEach是对数组的每一个元素执行一次给定的函数
2. map是创建一个新数组,该新数组由原数组的每个元素都调用一次函数的返回值
3. pop删除数组的最后一个元素,返回被删除的元素
4. push将一个或多个元素添加至数组的末尾,并返回数组的长度
5. shift删除数组的第一个元素,并返回删除元素
6. unshift将一个或多个元素添加至数组开头,并返回数组长度
7. splice通过删除或替换现有元素或者原地添加新的元素来修改数组,并以数组的形式返回被修改的内容
8. rerverse反转数组
闭包和作用域
闭包是作用域应用的特殊场景,js的常见作用域包括全局作用域、函数作用域、块级作用域。
常见闭包的使用常见:函数作为参数被传递、函数作为参数被返回。
手写new关键字
在js中new关键字主要做了:创建空对象,对象会作为执行new构造函数之后返回的对象实例,将指向空对象的原型指向构造函数的prototype属性,同时将空对象复赋值给函数内部的this。并执行构造函数的逻辑,返回初始创建的对象或构造函数的显性返回值。
箭头函数和普通函数的区别
箭头函数不会创建自身的this,只会从上一级继承this,箭头函数的this在定义时就已经确定,之后就不会更改。同时箭头函数无法作为构造函数使用,没有自身的prototype,也没有arguments。
迭代器与生成器的关系
任意一个对象实现了遵守迭代器协议的[Symbol.iterator]方法,那么该对象就可以调用[Symbol.iterator]返回一个遍历器对象。生成器函数就是遍历器生成函数,故可以把生成器赋值给对象的[Symbol.iterator]属性,从而使该对象具有迭代器接口
浏览器事件循环机制
Js是单线程(同一时间只能干一件事),同时还是非阻塞运行的(执行异步任务时,会挂起相应任务,待异步返回结果再执行回调)。
在js执行代码时,会将对象储存在堆中,在栈中记录对象在堆中的地址值,同时还会记录基础数据类型变量。
type与interface区别
interface可以重复声明,type不行。
继承方式不同,type使用交叉类型方式&,interface使用extends实现。在对象扩展的情况下,使用接口继承要比交叉类型的性能更好。建议使用interface来描述对象对外暴露接口。使用type将一组类型重命名。
Any、unkonwn、never
any与unkonwn在TS类型中属于顶层TopType,即所有的类型都是他们的子类型。而never则相反,它作为Bottom type是所有类型的子类型。
常见工具类型:
1. Partial:满足部分属性即可
2. Required:所有属性都需要
3. Readonly:包装后所有属性只读
4. Pick:选取部分属性
5. Omit:去除部分属性
6. Extract:交集
7. Exclude:差集
虚拟Dom
采用虚拟DOM的更新技术在性能上理论上不可能比原生js操作DOM高。开发者很难写出绝对优化的命令式代码。所以虚拟DOM就是用来解决这一问题,让开发者在代码的性能上得到保障,甚至无限接近命令式代码的性能。
1. vue2中使用的是双端·diff算法:是一种同时比较新旧两组节点的两个端点算法(比头、比尾,头比尾、尾比头)。
2. vue3中使用快速diff算法:它借鉴文本diff算法的预处理思路,先处理新旧两组节点中相同的前置节点和后置节点。当全部处理完毕后进行比对,构建一个最长递增子序列。
Vue3双向绑定的实现
Vue3实现双向绑定的核心是Proxy(代理),它会对需要响应式处理的对象进行一层代理,对象的所有操作都会被Proxy代理。
Vue中ref、toRef、toRefs
1. ref接受一个内部值,生成对应的响应式数据,该内部值挂载在ref对象的value属性上。
2. toRef为响应式对象的一个属性创建对应的ref。
3. toRefs将响应式对象转换成普通对象
浏览器渲染页面的过程
首先输入网址,浏览器会向服务器发起DNS请求,得到相应的IP地址,之后进行tcp三次握手与服务器建立连接,连接建立后,浏览器会代表用户发送一个初始的GET请求,通常是请求HTML文件。服务器收到对应请求后,会根据相关的响应头和HTML内容进行回复。
一旦浏览器拿到数据,机会开始解析信息,这个过程浏览器会根据HTML文件构建DOM树,当遇到同步资源,会停止DOM树生成,执行同步资源。在构建DOM树时,浏览器主线程是被占据的,不过浏览器的预加载扫描器会去请求高级优先级的资源,预加载扫描器很好的解决了单线程的阻塞问题。接下来浏览器会处理css生成cssDOM树,将css规则转换为可以理解和使用的样式映射。当有了DOM树和cssDOM树,浏览器会将其组合生成一个render树,计算样式或渲染树会从DOM的根节点开始构建。遍历每一个可见节点(将相关的样式匹配到每一个可见节点上),接下来开始布局,该过程(依旧从根节点开始)会确定所有节点的宽高位置,通过渲染器将其绘制在页面上。绘制完成了并不代表交互也都生效了,因为主线程可能还无法抽出时间去处理滚动、触摸等交互,要等到js加载完成,同时主线程是空闲状态。
Webpack优化方案
基于esm的tree shaking
对babel设置缓存,缩小babel-loader的处理范围,及精准指定要处理的目录。
压缩资源
配置资源的按需导入
设置CDN优化
前端权限设计思路
项目中,尤其是管理后台必不可少的一个环节就是权限设计。通常一个系统的不同用户会对应不同的角色,不同角色对应不同组织。在进入管理后台的时候会去请求对应的权限接口,这个接口是与后台约定好的权限标识内容。
什么情况会重绘和回流
浏览器请求对应页面资源时,会将HTML解析为DOM树,CSS解析成CSSOM树,然后将DOM树与CSSOM树合并产生render树,浏览器根据render树计算节点在页面的位置大小,最后将节点绘制在页面上。
当render tree中部分或全部元素的尺寸、结构、属性发生变化,浏览器就会重新渲染页面,这个就是浏览器的回流。
当页面的元素样式的改变不影响它在文档流的位置时(颜色变化),这就是重绘。
回流必定导致重绘,重绘不一定会引起回流,回流比重绘代价更高。
常见改善方案:
1. 在频繁进行操作时,可以使用防抖和节流来控制频率。
2. 避免频繁的操作DOM
3. 复杂动画可以使用绝对定位,脱离文档流,否则他会频繁引起父元素及其后续元素的回流
大量数据如何优化
大量数据使用异步接收,对数据进行分片处理,渲染如果是采用长列表,可以使用虚拟列表(当前页面需要渲染的数据进行渲染,监听交互事件来切换渲染数据)
手写深拷贝
Function deepClone(obj){
//判断是否是对象以及是否为null,不是对象直接返回
if(typeof obj !== “object” || obj === null) obj
//创建返回值的对象,并对值进行初始化 Object and Array
const result = obj instanceof Array ? [] : {}
//遍历对象,如果属性值还是对象,递归调用函数
for(const key in obj){
if(obj.hasOwnProperty(key)){
result[key] = deepClone(obj[key])
}
}
return result
}
手写防抖与节流函数
//防抖函数
function(fn,delay){
let timer
return function(){
if(timer){
clearTimeout(timer)
}
timer = setTimeout(()=>{
fn,apply(this,arguments);
timer = null
},delay)
}
}
//节流
function(fn,delay){
let timer;
return function(){
if(timer) return
timer = setTimeout(()=>{
fn.apply(this,arguments);
timer = null
},delay)
}
}