1.简历中的过往项目经历会展开来问包括技术点(注意逻辑及方法论)
2.核心优势中描述的技术点(必问),面试官考察是否如简历描述的那样熟悉
#1、vue\react
都是创建UI得javaScript库
基于组件开发
都使用虚拟DOM
TS
3.您了解或理解哪些常见的设计模式
设计模式是一套通用得可复用得解决方案,用来解决在软件设计中得通用问题
工厂模式:封装实例得创建过程
单例模式:全局只有一个实例,如TS
观察者模式:比较常见
迭代器模式:除了for和forEach,还有iterator
装饰器模式:
原型模式:原型和原型链是js基础知识
代理模式:如Vue3中得proxy
JS
1.用setTimeout实现一个setInterval
setInterval会将回调函数放在任务队列前还是任务队列后,取决于当前执行的上下文(JS运行环境)和其他任务得优先级
*使用递归函数,不断去调用setTimeout达到setInterval的效果
1 | function mySetInterval(fn, millisec,count){ |
2.怎么理解闭包的
闭包是能读取外层函数内部变量的函数
访问所在作用域
函数嵌套
在所在作用域外被调用
适用的场景:
1、返回值;
1
2
3
4
5
6
7
8
9 //1.返回值 最常用的
function fn(){
var name="hello";
return function(){
return name;
}
}
var fnc = fn();
console.log(fnc())//hello
2、函数赋值
1
2
3
4
5
6
7
8
9
10 var fn2;
function fn(){
var name="hello";
//将函数赋值给fn2
fn2 = function(){
return name;
}
}
fn()//要先执行进行赋值,
console.log(fn2())//执行输出fn2
3、自执行函数
1
2
3
4
5
6
7
8
9
10
11
12 (function(){
var name="hello";
var fn1= function(){
return name;
}
//直接在自执行函数里面调用fn2,将fn1作为参数传入
fn2(fn1);
})()
function fn2(f){
//将函数作为参数传入
console.log(f());//执行函数,并输出
}
for循环中通过定时器输出i
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 for( var i=0;i<5;i++){
setTimeout(function(){
console.log(i);
}
,0);
}
// 输出结果 5 5 5
for( var i=0;i<5;i++){
(function(lockedIndex){
setTimeout(function(){
console.log(lockedIndex);
}
,0);
})(i);
}
// 输出 "1,2,3,4,5"
/**
*
*/
for( let i=0;i<5;i++){
setTimeout(function(){
console.log(i);
}
,0);
}
// 输出 "1,2,3,4,5"
/**
* let 有块级作用域
*
*/
4、循环赋值
5、setter和getter;
6、迭代器(执行一次函数往下取一个值)
1
2
3
4
5
6
7
8
9
10
11
12
13var arr =['aa','bb','cc'];
function incre(arr){
var i=0;
return function(){
//这个函数每次被执行都返回数组arr中 i下标对应的元素
return arr[i++] || '数组值已经遍历完';
}
}
var next = incre(arr);
console.log(next());//aa
console.log(next());//bb
console.log(next());//cc
console.log(next());//数组值已经遍历完
3.作用域、原型链
原型链:对象之间的继承关系通过构造函数的prototype指向父类对象,直到指向Object对象为止形成的指向链条。
通俗讲: 原型链是原型对象创建过程的历史记录。
注:在javascript中,所有的对象都拥有一个**__proto__属性指向该对象的原型prototype** 。
特殊:
1、函数的显示原型指向的对象默认是空的Object对象实例,但是Object本身除外
1 | function Fun() {} |
2、Object 的原型对象是原型链的尽头!它的原型对象的隐式原型指向 null
1 | console.log(Object.prototype.__proto__ === null); // true |
3、所有函数都是Function的实例,Function本身也是 (即:Function = new Function)
instance of的实现
1
2
3
4
5
6
7
8
9function instanceofF(A, B) {
var L = A.__proto__;
var R = B.prototype;
if (L === R) {
//A的内部属性__proto__指向B的原型对象
return true;
}
return false;
}
作用域就是限制变量只能在某个区域内有效
函数提升优先于变量提升
变量提升:在当前上下文中,js代码自上而下执行之前,会先做一些代码解析的工作,处理一下变量的声明
4.原生JS实现一个拖拽库,说一下思路
5.JS数据类型说一下
8种
基本数据类型: undefined、Null、Number、Boolean、String、
ES6新增
Symbol:创建后独一无二不可改变,为解决全局变量冲突的问题
BigInt:数字类型的数据,可表示任意精度格式的整数,用来存储和操作大整数
复杂数据类型:Array、Object、Function
检测数据类型的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
271、typeof // 基本数据类型
2、instance of // 只能判断引用型数据Object
3、constructor // 不能判断null和undefined,如果创建一个对象来改变它的原型,constructor就不能用来判断数据类型了;
4、Object.prototype.toString.call() // 都可以判断
//判断基本数据类型
console.log(Object.prototype.toString.call(123456)) // [object Number] --数字
console.log(Object.prototype.toString.call('hello world'))// [object String] --字符串
console.log(Object.prototype.toString.call(null)) // [object Null] --Null
console.log(Object.prototype.toString.call(true)) // [object Boolean] --布尔型
console.log(Object.prototype.toString.call(undefined)) // [object Undefined]--Undefined
//判断原生引用类型(部分):
function fun() {}
console.log(Object.prototype.toString.call(fun)) // [object Function] --函数
var now = new Date();
console.log(Object.prototype.toString.call(now)) // [object Function] --日期
var arr = [1,2,3,4,5];
console.log(Object.prototype.toString.call(arr)) // [object Array] --数组
var obj = {name:'ZhangSan', age:25}
console.log(Object.prototype.toString.call(obj)) // [object Object] --对象
var reg = /^1[3456789]\d{9}$/
console.log(Object.prototype.toString.call(reg)) // [object RegExp] --正则表达式
5、ES6继承 https://www.jb51.net/article/230913.htm
本质上所有的继承都离不开原型链
1、原型链继承—extends
缺点: 多个实例会导致原型对象上的内容时共享的,内容之间会互相影响
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19function ParentClass() {
this.name = '一碗周'
}
ParentClass.prototype.getName = function () {
return this.name
}
// 定义子类,将来用于继承父类
function ChildClass() {}
// * 将子类的原型指向父类的实例化,子类拥有父类实例化后的内容
ChildClass.prototype = new ParentClass()
// 将子类进行实例化
var child = new ChildClass()
console.log(child.getName()) // 一碗周
2、借助构造函数继承: 缺点不会继承父类原型对象上的方法和属性
3、组合式继承:
使用原型链或原型式继承实现对原型的属性和方法的继承。
通过结构构造函数实现对实例对象的属性的继承。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// 父级对象
function Parent() {
this.parent = 'parent'
}
// 为 Parent 父级对象的原型增加属性
Parent.prototype.name = '一碗周'
// 子级对象
function Child() {
this.child = 'child'
// 使用 call() 或者 apply() 方法调用父级构造函数 实现继承。
Parent.call(this)
}
// 解决不会继承构造函数的原型对象的问题
Child.prototype = Parent.prototype
const child = new Child()
console.log(child.name) // 一碗周
4: 原型式继承
Object.create()方法实现继承
ES6的class类 https://blog.csdn.net/weixin_44691513/article/details/108416033
ES6 的class与ES5写法的几个核心注意点:
ES5 的构造函数Point,对应 ES6 的Point类的构造方法。
类的所有方法都定义在类的prototype属性上面。
定义“类”的方法的时候,前面不需要加上function这个关键字,直接把函数定义放进去了就可以了
方法之间不需要逗号分隔,加了会报错
ES6的class使用方法与ES5的构造函数一模一样
constructor方法是类的默认方法,通过new命令生成对象实例时,自动调用该方法。一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。
类必须使用new关键字来调用
Class的静态属性和方法
static 表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”
super
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17class Person{
constructor(name){
this.name=name;
this.sex="男";
}
}
class Student extends Person{
constructor(name,age){
super(name);
this.age=age;
}
}
let s=new Student("张三",11);
console.log(s.name);
console.log(s.age);
console.log(s.sex);
ES6 为new命令引入了一个new.target属性,该属性一般用在构造函数之中,返回new命令作用于的那个构造函数。
如果构造函数不是通过new命令调用的,new.target会返回undefined,因此这个属性可以用来确定构造函数是怎么调用的。
6.JS的GC(垃圾回收)机制 https://blog.csdn.net/qq_42543177/article/details/124644363
垃圾回收不是实时的,会周期性的释放程序中已经不在被引用的垃圾对象
判断是否被引用的方法
1、标记清除法
这是目前浏览器大多基于标记清除法。我们可以分为两个阶段:
标记:从根节点遍历为每个可以访问到的对象都打上一个标记,表示该对象可达。
清除:在没有可用分块时,对堆内存遍历,若没有被标记为可达对象就将其回收。
优点:实现简单。
缺点:a 内存过于碎片化。
b 内存分配速度慢。
解决方法:标记-整理法
标记整理法和标记清除法标记阶段一致,只是整理阶段是先将被引用的对象移动到一端,然后清理掉标记的内存。
2、引用计数法: 引用计数法就是追踪每个变量被引用的次数,当引用数为0将可以被回收掉。
优点:当引用数为0时会被立即回收
缺点:a 计数器的增减处理频繁,会导致空间的使用效率降低。
b 循环引用无法收回,导致内存泄漏。
7.JS高级函数
map、filter、reduce、sort、every、some、find、findIndex
CSS
1.清除浮动的方法
浮动的原理:使当前元素脱离文档流
*1 父元素设置overflow: hidden/auto;浏览器会自动检查浮动区域的高度
*2 结尾处添加div空标签设置clear:both;
3 父元素div定义高度
2.CSS选择器
基础: 通配符 、标签、类(class)、id、
结构: 后代(包含)选择器(用空格隔开)、子代选择器(>)、兄弟选择器(~)
属性:
伪类:动态伪类(:link :visited :active :hover :focus)、结构伪类
::
权重值大小比较:!important>行内样式>id选择器>class选择器=伪类选择器=属性选择器>标签选择器=伪元素选择器>通配符选择器>继承样式。
就近原则: 相同权重的选择器,哪个选择器最后定义的,就选择哪个选择器
3.styled-components sass less的区别
styled-components: 是一个使用**CSS-in-JS技术**实现的样式组件库,
它是一个为React和React Native设计的库。它允许我们在应用中使用JavaScript和CSS混合起来编写样式级组件。并且它是支持Sass的,不需要添加任何库。
**sass、less 都是css预编译处理器** https://blog.csdn.net/weixin_62765236/article/details/127332140
*1 编译环境不同 sass安装需要ruby环境、在服务端处理的 less通过js编译,在客户端处理
*2 变量符不同 less@ sass $
*3 sass支持条件语句, less不支持
*4 sass有输出设置、less没有
sass工具库 compass lessUI库 bootstrap
*5 引入外部文件不同 sass 引用的外部文件命名必须以_开头
less引入外部文件和css@import没有什么差别
4.盒模型
标准盒模型:box-sizing: content-box
IE盒模型: box-sizing: border-box
5.CSS动画
transition: 渐变动画
transform: 转变动画
animation: 自定义动画库
6.水平垂直居中 https://blog.csdn.net/weixin_44370837/article/details/116602151
绝对定位+transform
绝对定位+margin
绝对定位+ margin auto 父子元素宽高都未知
1
2
3
4
5
6
7
8 .work2 {
position: absolute;
top: 0;
bottom: 0;
right: 0;
left: 0;
margin:auto;
}
父元素使用flex布局,并设置相关的属性值为center
使用table-cell实现
1
2
3
4
5
6
7
8
9
10.par-work2 {
height: 500px;
width: 500px;
display: table-cell;
vertical-align: middle;
text-align: center;
}
.son-work2 {
display: inline-block;
}
使用grid布局
1
2
3
4
5
6
7
8.par-work3 {
display: grid;
height: 500px;
}
.son-work3 {
align-self: center; /*设置单元格内容的垂直位置*/
justify-self: center; /*设置单元格内容的水平位置*/
}
7、css常见的布局
圣杯布局:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43 <title>圣杯布局</title>
<style>
*{
margin: 0;
padding: 0;
}
.center{
padding: 0 200px;
}
.middle,.left,.right{
float: left;
height: 50px;
}
.middle{
width: 100%;
background: pink;
}
.left,.right{
width: 200px;
}
.left{
background: red;
margin-left: -100%;
position: relative;
left: 200px;
}
/*为什么要使用定位
因为center添加了padding,意味着盒子宽度增加了,原来设置左右盒子的位置也就发生了变化,设置相对定位,偏移padding左右的值就可以在视觉上实现相应的功能 */
.right{
background: green;
margin-left: -200px;
position: relative;
left: 200px;
}
</style>
</head>
<body>
<div class="center"><div class="middle">中间</div></div>
<div class="left">左边</div>
<div class="right">右边</div>
</body>
双飞翼布局
是针对圣杯布局的一个优化方案(使用了定位).解决方法就是在center中在添加一个一个inner盒子,并为其设置margin-left和margin-right,这样中间盒子的内容区域就不会被覆盖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>双飞翼布局</title>
<style>
*{
margin: 0;
padding: 0;
}
.center{
width: 100%;
background: pink;
}
.center,.left,.right{
float: left;
height: 50px;
}
.left,.right{
width: 200px;
}
.left{
background: red;
margin-left: -100%;
}
.right{
background: green;
margin-left: -200px;
}
.middle{
margin-left: 200px;
margin-right: 200px;
}
body{
min-width: 900px;
}
</style>
</head>
<body>
<div class="center">
<div class="middle">中间</div>
</div>
<div class="left">左边</div>
<div class="right">右边</div>
</body>
</html>
React
1.redux中间件,用过哪些
redux-thunk
redux-saga
redux-promise
3.redux和context怎么抉择用哪个
redux:
4.用context实现一个redux说一下思路(用哪些hook)
5.useReducer
useReducer: 接受两个参数,reducer函数、初始的state
返回值:useReducer 会返回一个有状态的值和一个设置该状态的函数
可读性: 可以将状态更新逻辑和事件处理程序分离
可调试性:可以在reducer函数中打印日志
每个 action 都描述了一个单一的用户交互
6.useRef
获取dom元素/获取组件实例/ 用来存储可变数据
7.useMemo React.memo,单独说一下,对比说一下
useMemo: 入参创建的回调函数、依赖的数组
依赖的数据项改变才会重新计算,如果不设置依赖数据项,每次都会重新计算
React.memo:当其作用于函数式组件并且作为子组件时, 每次父组件更新后, 会浅对比传来的 props 是否变化, 若没变化, 则子组件不更新
减少了组件内重复的计算、优化组件渲染
useCallBaack和useMemo
useCallBaack 主要用来缓存回调函数,避免不必要的函数创建和重复渲染
useMemo用于缓存计算结果,避免不必要的重复计算,适用于计算开销较大的操作或昂贵的函数调用的场景。
8.封装过哪些hook,描述思路
使用过react的hook库 ahooks
封装一些公共的数据处理逻辑
如何去存储
如何去更新 同步reducer, 异步action
9.怎么自定义hooks,实现redux状态管理
浏览器、HTTP
1.常用的短链请求有哪些?什么区别
websocket:WebSocket是一种基于TCP协议的、双向的、实时的短连接协议,可以用于实现即时通讯、实时数据传输和游戏等应用。WebSocket的实现方式主要有两种:客户端-服务器模型和服务器-客户端模型。
http短链接:HTTP短连接是一种基于HTTP协议的临时连接,可以用于实现数据传输或共享资源,通常持续时间非常短,只有几秒钟到几分钟。HTTP短连接的实现方式主要有两种:基于请求响应模型和基于状态模型。
WebSocket++:WebSocket++是一种C++库,可以用于实现WebSocket协议。WebSocket++支持多种平台,包括Windows、Linux和Android等
.命令行接口:命令行接口是一种通过命令行界面进行短连接创建和管理的接口,通常使用在嵌入式系统中。命令行接口可以通过编写C或C++程序来实现,并支持多种协议,如HTTP、FTP和SMTP等。
WebSocket客户端库: WebSocket客户端库是一种C或C++库,可以用于实现WebSocket协议的客户端应用程序。这些库通常提供创建和管理短连接的API,并支持多种平台和协议。
HTTP的长连接和短连接本质上是TCP长连接和短连接。
HTTP属于应用层协议,在传输层使用TCP协议,在网络层使用IP协议。
IP协议主要解决网络路由和寻址问题,TCP协议主要解决如何在IP层之上可靠的传递数据包,使在网络上的另一端收到发端发出的所有包,并且顺序与发出顺序一致。TCP有可靠,面向连接的特点。
http1.0 默认是短链接,浏览器和服务器每进行一次HTTP操作,就进行一次链接,任务结束后链接中断
但从 HTTP/1.1起,默认使用长连接,用以保持连接特性。使用长连接的HTTP协议
1
2Connection:keep-alive
// Keep-Alive不会永久保持连接,它有一个保持时间,可以在不同的服务器软件(如Apache)中设定这个时间。实现长连接要客户端和服务端都支持长连接。
TCP长连接 client向server发起连接, server接受client链接,双方建立连接 依赖于TCP的保活功能
如果一个给定的连接在两小时内没有任何的动作,则服务器就向客户发一个探测报文段,客户主机必须处于以下4个状态之一:
客户主机依然正常运行,并从服务器可达。客户的TCP响应正常,而服务器也知道对方是正常的,服务器在两小时后将保活定时器复位。
客户主机已经崩溃,并且关闭或者正在重新启动。在任何一种情况下,客户的TCP都没有响应。服务端将不能收到对探测的响应,并在75秒后超时。服务器总共发送10个这样的探测 ,每个间隔75秒。如果服务器没有收到一个响应,它就认为客户主机已经关闭并终止连接。
客户主机崩溃并已经重新启动。服务器将收到一个对其保活探测的响应,这个响应是一个复位,使得服务器终止这个连接。
客户机正常运行,但是服务器不可达,这种情况与2类似,TCP能发现的就是没有收到探查的响应。
2.浏览器缓存
浏览器缓存也称为HTTP缓存,HTTP缓存简单理解就是本地(浏览器)缓存了HTTP响应,以便后续复用,减少向服务端的请求。
基于url缓存资源
强缓存: 直接使用浏览器缓存, 注意有效期
1
2
3
4
5
6HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1024
Date: Tue, 22 Feb 2022 22:22:22 GMT
Cache-Control: max-age=3600 //3600秒,表示一个小时内有效, 最大有效时长
协商缓存:浏览器缓存过期,向服务端发起请求询问资源是否变化,服务端判断无变化,返回304 浏览器使用本地缓存内容并更新有效期, 如果变了返回200 + 新的资源 浏览器缓存会更新
● last-modified:资源最后修改时间。
● ETag:资源的唯一编码,文件内容变更后更新。
3、✔️触发协商缓存的条件
● Cache-Control:no-cache :强制使用协商缓存。
● 本地缓存过期,或Cache-Control: max-age=0
响应header返回:Last-Modified
请求header携带:If-Modified-Since
服务资源获取时间无法判断以后使用ETag
响应header返回:ETag
请求header携带:If-None-Match
实践:
● 不经常变的静态资源,如JS、CSS、图片推荐使用强制缓存,Cache-Control: max-age=31536000。
● HTML文档推荐使用协商缓存,比如SPA的入口页面可以使用Cache-Control: no-cache强制每次都使用协商缓存。
● Last-Modified、ETag可同时使用,ETag优先级更高,但Last-Modified还有额外的价值,可用来标识文件的修改时间。
● 合理定制不同资源文件的缓存机制、缓存周期。
● 缓存的Header配置都是在服务端,可以通过Nginx配置。
3.浏览器存储
web storage localStorage sessionStorage
http Cookie
一开始是用与服务端通信
document.cookie去获取
键值对用;隔开, 保存Set-Cookie
4.跨域是怎么产生的
域名的协议、ip、端口三者有一个不同就会产生跨域
原因:由于浏览器的同源策略
5.HTTPS安全性怎么实现的
SSL传输加密,身份认证
1、信息保密,通过使用公开密钥和对称密钥的技术加密信息
2、信息完整性,确保SSL业务全部达到目的
SSL利用机密共享和hash函数组提供信息完整性服务,确保服务器和客户机之间的信息内容免受破坏。
3、双向认证,客户机和服务器相互识别的过程
4、SSL的安全性服务对终端用户来讲做到尽可能透明
HTTP2.0 https://zhuanlan.zhihu.com/p/89471776
1、是在1x的基础上的升级
2、2.0重点是对终端用户的感知延迟,网络以及服务器资源的使用等性能优化
二进制分帧:改善传输性能,实现低延迟和高吞吐量
在二进制分帧层上,http2.0会将所有传输信息分割为更小的消息和帧,并对它们采用二进制格式的编码将其封装,新增的二进制分帧层同时也能够保证http的各种动词,方法,首部都不受影响,兼容上一代http标准。其中,http1.X中的首部信息header封装到Headers帧中,而request body将被封装到Data帧中。
多路复用/连接共享
头部压缩
http1.x的头带有大量信息,而且每次都要重复发送。
http/2使用encoder来减少需要传输的header大小,通讯双方各自缓存一份头部字段表,既避免了重复header的传输,又减小了需要传输的大小
请求优先级:
●优先级最高:主要的html
●优先级高:CSS文件
●优先级中:js文件
●优先级低:图片
**服务端推送**
Node
1.了解到node的相关库
sequelize、cors
egg
express
Git
1.git相关问题,git命名,gitflow等
ES6
1.promise 装饰器 promise常用方法,事件循环
promise API
状态:PromiseState pending、resolved、rejected
状态一旦变化是不可逆的
且一个promise对象只能改变一次
无论变为成功还是失败,都会有一个结果数据
成功的结果数据一般称为value,失败的结果数据一般称为reason
结果:promiseResult
通过resolve、reject来改变
https://blog.csdn.net/qq_52788258/article/details/127832724
Promise.all方法:(promises) => {}
事件循环
当JS引擎主线程执行JS代码时,会判断其是否为异步任务,若是异步任务则会立即交给webAPIs处理,若是同步任务则继续执行。
webAPIs得到异步任务后,会根据异步任务要求,开启对应的新线程处理,当开启的新线程执行完毕后,就会将异步任务的回调函数加入到 (异步宏任务队列)中被加入到(异步宏任务队列)的回调函数不会立即进入执行栈执行,而是等待所有同步任务执行完后,JS引擎主线程会来异步宏任务队列中捞取队首位置的回调函数,放到执行栈中执行。
JS引擎主线程在将执行栈中的同步任务执行完后,就会不停地去异步宏任务队列中捞取回调函数,如果捞取到则压入执行栈中执行,执行完后,再去异步宏任务队列中捞取,如果捞取不到,则会不停地捞取,重复以上动作,所以叫事件循环。
而JS主线程在事件循环机制中,会先依次捞取完异步微任务队列中的所有回调函数到执行栈中执行,当异步微任务队列空了之后,才会去异步宏任务队列中捞取回调函数到执行栈中执行
其他
1.react hook常用的方法有哪些
2.next最新版的特性
3.react最新特性
hooks 16.8引入的
react18:
Suspense for Data fetching(数据获取的暂停)
状态更新引入了自动批处理,该特性是自动的,不用做任何配置
**startTransition()**函数可让你优化一些渲染较慢的操作
useDeferredValue() hook上进行了一些改进。这个hook用于延迟更新,从而提高应用程序的性能
4.安全攻击性问题(浏览器安全的方法是,如果被攻击了怎么解决等)
5.性能优化您了解多少,说说您的了解,性能优化实践
http请求优化
资源加载优化
页面渲染优化: 减少页面的don操作、采用css动画、避免table
代码优化
6.ts规则、泛型
any类型和unknow类型的区别、
- any类型
- 特点:
完全绕过了TS的类型检查,可以赋值和接受任何类型的值
对变量的任何操作都不会触发类型错误。
相当于关闭了类型系统的保护。
- unknown类型
- 特点:
表示未知类型,比any更严格,是类型安全的替代方案
可以接收任意类型的值,但是不能直接操作(除非先进行类型检查和类型断言)
强制类型安全
使用场景:
处理动态API响应
类型安全的动态渲染
- 特点:
**8.平常怎么提升自己技术,看什么书、什么论坛等